Skip to main content

Supplier Portal — Invoices

These endpoints let a supplier (prestador) manage their own invoices directly from the API: list them, open one for detail, declare the amount they are billing, declare many at once, and check an amount against the company tolerance before sending it. Every endpoint is scoped to the supplier account behind the token — you only ever see and touch your own invoices.

Supplier account required

The authenticated user must be linked to a supplier (prestador). Requests from a non-supplier account are rejected with 403 FORBIDDEN. All endpoints require a valid JWT token, API key, and tenant header. See Authentication.


List Invoices​

Retrieve a paginated list of the supplier's invoices for a date range, with optional status and free-text search. Each row carries the system amount, the declared amount, and the difference between them. The response also includes the tolerance that applies to the supplier so you can interpret the differences.

GET/apidev/v1/supplier-portal/invoices
PermissionAPICLI_PORTALPROVEEDOR_READ
Rate Limit30 req/min (sliding window)

Request Headers​

Every request to a protected endpoint requires these headers:

HeaderRequiredDescription
AuthorizationYesBearer token obtained from the Login endpoint. Format: Bearer <token>
X-API-KeyYesCompany integration key provided during onboarding. Format: gtk_xxx...
tenantYesYour assigned tenant domain (default: geotareas.com) — always send your assigned tenant
Content-TypeConditionalapplication/json — required for POST and PUT requests

Query Parameters​

ParameterTypeRequiredDescription
startdatestring (ISO 8601)YesStart of the date range
enddatestring (ISO 8601)YesEnd of the date range (range may not exceed 93 days)
statusstringNoFilter by invoice state code: PEN, ENV, APR, REV, REC, AJU, LIQ
searchstringNoFree-text match on service number, account, or invoice number (max 120 characters)
limitintegerNoRecords per page. Min: 1, Max: 100, Default: 25
offsetintegerNoRecords to skip. Default: 0

Response Fields — data.rows[]​

FieldTypeDescription
invoice_idstringInvoice unique identifier
invoice_datestring | nullInvoice date
service_idstringRelated service/task ID
service_numberstring | nullService display number
service_call_datestring | nullWhen the service was requested
account_namestring | nullAccount the service belongs to
citystring | nullService city
system_amountnumberAmount calculated by the system
declaration_idstring | nullDeclaration ID, if the supplier already declared an amount
declared_amountnumber | nullAmount declared by the supplier
declared_notesstring | nullNotes the supplier added on the declaration
provider_invoice_numberstring | nullSupplier's own invoice number
provider_invoice_datestring | nullSupplier's own invoice date
state_codestringInvoice state code (PEN, ENV, …)
state_namestringInvoice state name
differencenumber | nullDeclared minus system amount
difference_pctnumber | nullDifference as a percentage of the system amount
attachment_urlstring | nullURL to the attached invoice file
attachment_filenamestring | nullOriginal file name of the attachment

Response Fields — data.tolerance​

FieldTypeDescription
modestring | nullTolerance mode: PCT, ABS, AMB, or null when none applies
tolerance_pctnumber | nullAllowed percentage difference
tolerance_absnumber | nullAllowed absolute difference
auto_approvebooleanWhether amounts within tolerance are approved automatically
sourcestringWhere the tolerance comes from: proveedor, global, or ninguna

Code Example​

curl -s "https://$TENANT/apidev/v1/supplier-portal/invoices?startdate=2026-05-01&enddate=2026-05-31&status=PEN&limit=10" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"

Example Response​

{
"success": true,
"data": {
"rows": [
{
"invoice_id": "7234567890123456789",
"invoice_date": "2026-05-03T15:02:00",
"service_id": "103878",
"service_number": "SRV-2026-0042",
"service_call_date": "2026-05-02T09:10:00",
"account_name": "Supermercado Centro",
"city": "Montevideo",
"system_amount": 1098.00,
"declaration_id": "8100000000045",
"declared_amount": 1100.00,
"declared_notes": "Incluye traslado.",
"provider_invoice_number": "A-0001-0000123",
"provider_invoice_date": "2026-05-03",
"state_code": "ENV",
"state_name": "Enviada",
"difference": 2.00,
"difference_pct": 0.18,
"attachment_url": "https://files.example.com/inv/123.pdf",
"attachment_filename": "factura-123.pdf"
}
],
"tolerance": {
"mode": "PCT",
"tolerance_pct": 5.0,
"tolerance_abs": null,
"auto_approve": true,
"source": "proveedor"
}
},
"meta": {
"total": 1,
"limit": 10,
"offset": 0
}
}

Invoice Detail​

Retrieve a single invoice with its full breakdown: the same row fields as the list, plus the line-item concepts and the tolerance that applies. Returns 404 if the invoice does not exist or does not belong to the supplier.

GET/apidev/v1/supplier-portal/invoices/{id}
PermissionAPICLI_PORTALPROVEEDOR_READ
Rate Limit30 req/min (sliding window)

Path Parameters​

ParameterTypeRequiredDescription
idstringYesInvoice unique identifier

Response Fields — data.concepts[]​

FieldTypeDescription
concept_idstringConcept catalog ID
descriptionstringConcept description
unit_amountnumberAmount per unit
quantitynumberQuantity
tax_pctnumberTax percentage applied
totalnumberLine total

The data object also includes every field listed for a list row and a tolerance object (see List Invoices).

Code Example​

curl -s "https://$TENANT/apidev/v1/supplier-portal/invoices/7234567890123456789" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"

Example Response​

{
"success": true,
"data": {
"invoice_id": "7234567890123456789",
"invoice_date": "2026-05-03T15:02:00",
"service_id": "103878",
"service_number": "SRV-2026-0042",
"account_name": "Supermercado Centro",
"city": "Montevideo",
"system_amount": 1098.00,
"declaration_id": "8100000000045",
"declared_amount": 1100.00,
"declared_notes": "Incluye traslado.",
"provider_invoice_number": "A-0001-0000123",
"provider_invoice_date": "2026-05-03",
"state_code": "ENV",
"state_name": "Enviada",
"difference": 2.00,
"difference_pct": 0.18,
"attachment_url": "https://files.example.com/inv/123.pdf",
"attachment_filename": "factura-123.pdf",
"concepts": [
{
"concept_id": "100",
"description": "Mano de obra",
"unit_amount": 900.00,
"quantity": 1,
"tax_pct": 22.0,
"total": 1098.00
}
],
"tolerance": {
"mode": "PCT",
"tolerance_pct": 5.0,
"tolerance_abs": null,
"auto_approve": true,
"source": "proveedor"
}
},
"meta": {}
}

Declare Invoice Amount​

Declare the amount the supplier is billing for an invoice. This is an upsert: if no declaration exists yet it is created, otherwise the existing one is updated. The response reports the resulting state and how the declared amount compares to the company tolerance.

POST/apidev/v1/supplier-portal/invoices/declare
PermissionAPICLI_PORTALPROVEEDOR_WRITE
Rate Limit10 req/min (sliding window)

Request Body​

FieldTypeRequiredDescription
invoice_idstringYesInvoice to declare (numeric string)
amountnumberYesDeclared amount. Must be >= 0
notesstringNoFree-text notes for the declaration
invoice_numberstringNoSupplier's own invoice number (max 60 characters)
invoice_datestring (ISO 8601)NoSupplier's own invoice date
tax_pctnumberNoTax percentage (0–100)

Response Fields — data.tolerance​

FieldTypeDescription
within_tolerancebooleanWhether the declared amount is within tolerance
differencenumberDeclared minus system amount
difference_pctnumberDifference as a percentage of the system amount
difference_absnumberAbsolute difference
actionstringResulting action (e.g. auto-approve or send to review)
config_sourcestringWhere the applied tolerance comes from

Code Example​

curl -s -X POST "https://$TENANT/apidev/v1/supplier-portal/invoices/declare" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"invoice_id": "7234567890123456789",
"amount": 1100.00,
"notes": "Incluye traslado.",
"invoice_number": "A-0001-0000123",
"invoice_date": "2026-05-03",
"tax_pct": 22
}'

Example Response​

{
"success": true,
"data": {
"declaration_id": "8100000000045",
"declared_amount": 1100.00,
"state_id": 101,
"tolerance": {
"within_tolerance": true,
"difference": 2.00,
"difference_pct": 0.18,
"difference_abs": 2.00,
"action": "AUTO_APPROVE",
"config_source": "proveedor"
}
},
"meta": {}
}

Declare Batch​

Declare amounts for many invoices in one request. Each item is processed independently, so the request always returns 200 with a per-item success or failure. Use this to push a whole period's declarations at once.

POST/apidev/v1/supplier-portal/invoices/declare-batch
PermissionAPICLI_PORTALPROVEEDOR_WRITE
Rate Limit10 req/min (sliding window)

Request Body​

FieldTypeRequiredDescription
declarationsarrayYesList of declarations (1–100 items)

Each item in declarations[] accepts the same fields as Declare Invoice Amount:

FieldTypeRequiredDescription
invoice_idstringYesInvoice to declare
amountnumberYesDeclared amount (>= 0)
notesstringNoFree-text notes
invoice_numberstringNoSupplier's own invoice number
invoice_datestring (ISO 8601)NoSupplier's own invoice date
tax_pctnumberNoTax percentage (0–100)

Response Fields — data​

FieldTypeDescription
resultsarrayOne entry per submitted item, in order
acceptednumberHow many items were declared successfully
rejectednumberHow many items failed

Each results[] entry includes invoice_id and success. On success it carries the same fields as a single declaration; on failure it carries an error describing why.

Code Example​

curl -s -X POST "https://$TENANT/apidev/v1/supplier-portal/invoices/declare-batch" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"declarations": [
{ "invoice_id": "7234567890123456789", "amount": 1100.00, "invoice_number": "A-0001-0000123" },
{ "invoice_id": "7234567890123456790", "amount": 540.00 }
]
}'

Example Response​

{
"success": true,
"data": {
"results": [
{
"invoice_id": "7234567890123456789",
"success": true,
"declaration_id": "8100000000045",
"declared_amount": 1100.00,
"state_id": 101,
"tolerance": {
"within_tolerance": true,
"difference": 2.00,
"difference_pct": 0.18,
"difference_abs": 2.00,
"action": "AUTO_APPROVE",
"config_source": "proveedor"
}
},
{
"invoice_id": "7234567890123456790",
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Invoice not found or not owned by this supplier."
}
}
],
"accepted": 1,
"rejected": 1
},
"meta": {}
}

Validate Amount (Pre-flight)​

Check an amount against the company tolerance before declaring it. This endpoint writes nothing — it only tells you how the amount would be treated. Returns 404 if the invoice does not belong to the supplier.

POST/apidev/v1/supplier-portal/invoices/validate
PermissionAPICLI_PORTALPROVEEDOR_READ
Rate Limit30 req/min (sliding window)

Request Body​

FieldTypeRequiredDescription
invoice_idstringYesInvoice to check
amountnumberYesAmount to test. Must be >= 0

Response Fields — data​

FieldTypeDescription
invoice_idstringInvoice that was checked
system_amountnumberAmount calculated by the system
declared_amountnumberAmount you submitted for the check
within_tolerancebooleanWhether the amount is within tolerance
differencenumberSubmitted minus system amount
difference_pctnumberDifference as a percentage of the system amount
difference_absnumberAbsolute difference
actionstringAction that would result (e.g. auto-approve or send to review)
config_sourcestringWhere the applied tolerance comes from

Code Example​

curl -s -X POST "https://$TENANT/apidev/v1/supplier-portal/invoices/validate" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"invoice_id": "7234567890123456789",
"amount": 1500.00
}'

Example Response​

{
"success": true,
"data": {
"invoice_id": "7234567890123456789",
"system_amount": 1098.00,
"declared_amount": 1500.00,
"within_tolerance": false,
"difference": 402.00,
"difference_pct": 36.61,
"difference_abs": 402.00,
"action": "REVIEW",
"config_source": "proveedor"
},
"meta": {}
}

Errors​

CodeHTTPApplies toDescription
VALIDATION_ERROR400AllInvalid params or body (e.g. missing startdate, amount below 0, more than 100 declarations)
INVALID_DATE_RANGE400ListDate range exceeds 93 days, or dates are invalid
UNAUTHORIZED401AllMissing or invalid JWT token / API key
TOKEN_EXPIRED401AllThe JWT was valid but has expired (1 hour lifetime)
FORBIDDEN403AllThe account is not a supplier — "This endpoint requires a supplier account." — or lacks the required permission
NOT_FOUND404Detail, Declare, ValidateInvoice does not exist or does not belong to your supplier account
RATE_LIMITED429AllExceeded the endpoint rate limit