Billing — Invoices (Read)
The Billing Invoices API lets you query invoices generated by the GeoTareas billing system, either created manually or through automation rules.
All endpoints on this page require a valid JWT token, API key, and tenant header. See Authentication for details.
These endpoints are documented but not yet implemented in the public API (/apidev/v1/billing/*). The internal billing services exist in geotareas/facturacion/ but have not been wired to the API developers module. This documentation reflects the planned contract — DTOs, controller routes, permissions, and tests are still pending.
List Invoices
Retrieve a paginated list of invoices with optional filters.
/apidev/v1/billing/invoicesRequest Headers
Every request to a protected endpoint requires these headers:
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer token obtained from the Login endpoint. Format: Bearer <token> |
X-API-Key | Yes | Company integration key provided during onboarding. Format: gtk_xxx... |
tenant | Yes | Your company hostname (e.g., yourcompany.geotareas.com) |
Content-Type | Conditional | application/json — required for POST and PUT requests |
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
from | date (YYYY-MM-DD) | Yes | — | Start date filter |
to | date (YYYY-MM-DD) | Yes | — | End date filter (max 90-day range) |
status | string | No | — | Status code: PENDIENTE, CONCILIADO, CERRADA, ANULADA |
type | string | No | — | Invoice type: PAGAR or COBRAR |
provider_id | string | No | — | Filter by provider ID |
vehicle_id | string | No | — | Filter by vehicle ID |
account_id | string | No | — | Filter by account ID |
client_id | string | No | — | Filter by client ID |
service_id | string | No | — | Filter by service/task ID |
tariff_id | string | No | — | Filter by tariff ID |
page | integer | No | 1 | Page number |
page_size | integer | No | 50 | Records per page. Max: 200 |
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Invoice unique identifier |
number_manual | string | null | Manual invoice number |
date | string | Invoice date (ISO 8601) |
type | string | PAGAR or COBRAR |
status.code | string | Status code |
status.name | string | Status display name |
status.behavior | integer | System behavior code (1=Pending, 2=Reconciled, 3=Closed, 9=Cancelled) |
currency.id | string | Currency ID |
currency.name | string | Currency name |
currency.symbol | string | Currency symbol |
service_id | string | Related service/task ID |
assistance_number | string | Assistance number |
provider.id | string | Provider ID |
provider.name | string | Provider name |
vehicle.id | string | Vehicle ID |
vehicle.plate | string | Vehicle plate |
account.id | string | Account ID |
account.name | string | Account name |
origin.id | string | Origin/procedencia ID |
origin.name | string | Origin/procedencia name |
tariff.id | string | Applied tariff ID |
tariff.name | string | Applied tariff name |
subtotal | number | Subtotal without taxes |
tax | number | Total tax amount |
total | number | Total with taxes |
subtotal_estimated | number | Estimated subtotal |
total_estimated | number | Estimated total |
impute_to | object | Imputation flags (client, account, provider, vehicle, personal, origin) |
notes | string | Observations |
created_at | string | Creation timestamp (ISO 8601) |
updated_at | string | Last update timestamp (ISO 8601) |
Code Examples
- cURL
- JavaScript
- Python
curl -s -X GET "https://api.example.com/apidev/v1/billing/invoices?from=2026-04-01&to=2026-04-03&status=PENDIENTE" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"
const params = new URLSearchParams({
from: '2026-04-01',
to: '2026-04-03',
status: 'PENDIENTE',
page_size: '50',
});
const response = await fetch(
`https://api.example.com/apidev/v1/billing/invoices?${params}`,
{
headers: {
'Authorization': `Bearer ${TOKEN}`,
'X-API-Key': APIKEY,
'tenant': TENANT,
},
}
);
const { data } = await response.json();
console.log(`${data.pagination.total} invoices found`);
import requests
response = requests.get(
'https://api.example.com/apidev/v1/billing/invoices',
headers={
'Authorization': f'Bearer {TOKEN}',
'X-API-Key': APIKEY,
'tenant': TENANT,
},
params={
'from': '2026-04-01',
'to': '2026-04-03',
'status': 'PENDIENTE',
}
)
data = response.json()['data']
print(f"{data['pagination']['total']} invoices found")
Response Example
{
"success": true,
"data": {
"items": [
{
"id": "7234567890123456789",
"number_manual": "001-0001",
"date": "2026-04-03T15:02:00",
"type": "PAGAR",
"status": { "code": "PENDIENTE", "name": "Pendiente", "behavior": 1 },
"currency": { "id": "1", "name": "Pesos Uy", "symbol": "$U" },
"service_id": "103878",
"assistance_number": "103490",
"provider": { "id": "5678", "name": "(CONT) Maldonado -San Carlos-Taller Sanca" },
"vehicle": { "id": "1013", "plate": "ABC 1234" },
"account": { "id": "41224", "name": "BRUNO MATIAS BARRETO PADILLA" },
"origin": { "id": "99", "name": "Servicios Sura" },
"tariff": { "id": "1", "name": "Tarifa General - Prestador" },
"subtotal": 900.00,
"tax": 198.00,
"total": 1098.00,
"subtotal_estimated": 900.00,
"total_estimated": 1098.00,
"impute_to": { "client": false, "account": false, "provider": true, "vehicle": false, "personal": false, "origin": true },
"notes": "Factura generada de forma automatica. (Externo)",
"created_at": "2026-04-03T15:02:00",
"updated_at": "2026-04-03T15:02:00"
}
],
"pagination": { "page": 1, "page_size": 50, "total": 1, "total_pages": 1 }
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
BILLING_DATE_RANGE_TOO_WIDE | 400 | Date range exceeds 90 days |
BILLING_INVALID_STATUS | 400 | Status code does not exist |
| Code | HTTP Status | Description | Resolution |
|---|---|---|---|
VALIDATION_ERROR | 400 | Request body or query parameters failed validation | Check the error.details field for specific validation failures |
UNAUTHORIZED | 401 | Missing, expired, or invalid JWT token or API key | Re-authenticate via Login to get a fresh token |
RATE_LIMITED | 429 | Too many requests — rate limit exceeded | Wait until the Retry-After header time elapses. See Rate Limits |
INTERNAL_ERROR | 500 | Unexpected server error | Retry after a brief delay. If persistent, contact support |
Invoice Detail
Retrieve the full detail of a single invoice including all line items.
/apidev/v1/billing/invoices/{id}Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Invoice unique identifier |
Response Fields
Includes all fields from the list endpoint, plus:
| Field | Type | Description |
|---|---|---|
assistance_number | string | Assistance number |
driver.id | string | Driver/conductor ID |
driver.name | string | Driver/conductor name |
client.id | string | Client ID |
client.name | string | null | Client name |
user.id | string | User who created the invoice |
user.name | string | User display name |
impute_to | object | Full imputation flags |
notes | string | Observations |
concepts | array | Invoice line items (see below) |
subtotal_estimated | number | Estimated subtotal |
total_estimated | number | Estimated total |
Concept fields:
| Field | Type | Description |
|---|---|---|
concept_id | string | Concept ID |
concept_name | string | Concept display name |
type | integer | Concept type code |
quantity | number | Quantity |
unit_price | number | Unit price |
subtotal | number | Line subtotal |
tax_percent | number | Tax percentage |
tax_amount | number | Tax amount |
total | number | Line total |
Response Example
{
"success": true,
"data": {
"id": "7234567890123456789",
"number_manual": "001-0001",
"date": "2026-04-03T15:02:00",
"type": "PAGAR",
"status": { "code": "PENDIENTE", "name": "Pendiente", "behavior": 1 },
"currency": { "id": "1", "name": "Pesos Uy", "symbol": "$U" },
"service_id": "103878",
"assistance_number": "103490",
"provider": { "id": "5678", "name": "(CONT) Maldonado..." },
"vehicle": { "id": "1013", "plate": "ABC 1234" },
"driver": { "id": "22", "name": "Juan Perez" },
"account": { "id": "41224", "name": "BRUNO MATIAS BARRETO PADILLA" },
"client": { "id": "0", "name": null },
"origin": { "id": "99", "name": "Servicios Sura" },
"tariff": { "id": "1", "name": "Tarifa General - Prestador" },
"user": { "id": "82", "name": "OB yuliana" },
"impute_to": {
"client": false,
"account": false,
"provider": true,
"vehicle": false,
"personal": false,
"origin": true
},
"notes": "Factura generada de forma automatica. (Externo)",
"concepts": [
{
"concept_id": "3",
"concept_name": "Movida",
"type": 1,
"quantity": 1.00,
"unit_price": 900.00,
"subtotal": 900.00,
"tax_percent": 22.00,
"tax_amount": 198.00,
"total": 1098.00
}
],
"subtotal": 900.00,
"tax": 198.00,
"total": 1098.00,
"subtotal_estimated": 900.00,
"total_estimated": 1098.00,
"created_at": "2026-04-03T15:02:00",
"updated_at": "2026-04-03T15:02:00"
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
BILLING_INVOICE_NOT_FOUND | 404 | Invoice not found or does not belong to the tenant |
Invoice Concepts
Retrieve only the line items of an invoice (useful when the full detail response is large).
/apidev/v1/billing/invoices/{id}/conceptsResponse Example
{
"success": true,
"data": {
"invoice_id": "7234567890123456789",
"concepts": [
{
"concept_id": "3",
"concept_name": "Movida",
"concept_unit": "Unidades",
"type": 1,
"quantity": 1.00,
"unit_price": 900.00,
"subtotal": 900.00,
"tax_percent": 22.00,
"tax_amount": 198.00,
"total": 1098.00
}
],
"subtotal": 900.00,
"tax": 198.00,
"total": 1098.00
}
}
Export Invoices
Export invoices to CSV or XLSX. Accepts the same filters as the list endpoint. Limited to 10,000 records.
/apidev/v1/billing/invoices/exportAdditional Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
format | string | csv | Export format: csv or xlsx |
include_concepts | boolean | false | Include line item detail per invoice |
| (+ all filters from List Invoices) |
Response
The response is a file download, not JSON:
- CSV:
Content-Type: text/csv; charset=utf-8 - XLSX:
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
curl -s -X GET "https://api.example.com/apidev/v1/billing/invoices/export?from=2026-04-01&to=2026-04-03&format=csv" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
--output invoices.csv
Errors
| Code | HTTP | Description |
|---|---|---|
BILLING_EXPORT_TOO_LARGE | 422 | Export exceeds 10,000 records |