Backend FEL API - RPAfelApi cURL Commands
Complete cURL reference for all backend endpoints that use RPAfelApi.
Configuration
# Base URL (default: http://localhost:4000)
export BASE_URL="http://localhost:4000"
# Firebase ID Token (get from browser dev tools or Firebase CLI)
export TOKEN="YOUR_FIREBASE_ID_TOKEN"
# Example UUIDs - Replace with actual values from your database
export BUSINESS_ID="your-business-uuid"
export SALE_ID="your-certified-sale-uuid"
export USER_ID="your-user-uuid"
export LOCATION_ID="your-location-uuid"
export CUSTOMER_ID="your-customer-uuid"
export CURRENCY_ID="your-currency-uuid"
1. Certify Invoice Document (FACT)
POST /fel/certify-document
Certifies an invoice document via RPAfelApi. This endpoint automatically:
- Converts Invoice to DTE JSON format
- Retrieves FEL credentials from business config
- Gets token from RPAfelApi (with caching)
- Sends to RPAfelApi for certification
- Handles retries and error cases
Basic Invoice
curl -X POST "${BASE_URL}/fel/certify-document" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"businessData": {
"id": "'"${BUSINESS_ID}"'"
},
"felProviderData": {
"providerName": "rpafelapi"
},
"invoiceNumber": "FAC-001",
"date": "2025-01-21",
"generalData": {
"type": "FACT",
"dateTimeIssue": "2025-01-21T10:00:00.000Z",
"currencyCode": "GTQ"
},
"issuerData": {
"taxId": "44653948",
"taxName": "LA LECHITA, SOCIEDAD ANONIMA",
"establishmentCode": "1",
"commercialName": "TUSA",
"vatAffiliationCode": "GEN",
"addressData": {
"address": "KM 55.5 CARRETERA INTERAMERICANA, CENTRO COMERCIAL ANDARIA LOCAL47 ZONA 4 CHIMALTENANGO, CHIMALTENANGO",
"postalCode": "04001",
"municipality": "Chimaltenango",
"department": "Chimaltenango",
"country": "GT"
}
},
"receiverData": {
"taxId": "CF",
"taxName": "CONSUMIDOR FINAL",
"addressData": {
"address": "CIUDAD",
"postalCode": "01010",
"municipality": "GUATEMALA",
"department": "GUATEMALA",
"country": "GT"
}
},
"phrases": [
{
"phraseType": "1",
"scenarioCode": "1"
}
],
"items": [
{
"name": "Product 1",
"unitOfMeasure": "UNI",
"goodOrService": "B",
"quantity": 2,
"unitPrice": 20.00,
"amount": 40.00,
"discount": 0.00,
"taxes": [
{
"shortName": "IVA",
"taxableUnitCode": "1",
"taxableAmount": 35.714285,
"taxAmount": 4.285714
}
]
}
],
"addendumData": {
"version": "7.1234654163",
"internalReference": "'"${SALE_ID}"'",
"dateReference": "2025-01-21T10:00:00.000Z",
"validateInternalReference": "VALIDAR"
},
"total": 40.00
}'
Invoice with Tip (Propina)
When an item has "PROPINA" or "TIP" in the name, the system automatically sets PropinaAdenda: "1":
curl -X POST "${BASE_URL}/fel/certify-document" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"businessData": {
"id": "'"${BUSINESS_ID}"'"
},
"felProviderData": {
"providerName": "rpafelapi"
},
"generalData": {
"type": "FACT",
"dateTimeIssue": "2025-01-21T10:00:00.000Z",
"currencyCode": "GTQ"
},
"issuerData": {
"taxId": "44653948",
"taxName": "RESTAURANT NAME, S.A.",
"establishmentCode": "1",
"commercialName": "RESTAURANT",
"vatAffiliationCode": "GEN",
"addressData": {
"address": "ADDRESS",
"postalCode": "01001",
"municipality": "Guatemala",
"department": "Guatemala",
"country": "GT"
}
},
"receiverData": {
"taxId": "49862952",
"taxName": "CUSTOMER NAME",
"taxpayerType": "NIT",
"addressData": {
"address": "ADDRESS",
"postalCode": "01001",
"municipality": "Guatemala",
"department": "Guatemala",
"country": "GT"
}
},
"phrases": [
{
"phraseType": "1",
"scenarioCode": "1"
}
],
"items": [
{
"name": "Meal",
"unitOfMeasure": "UNI",
"goodOrService": "S",
"quantity": 1,
"unitPrice": 100.00,
"amount": 100.00,
"discount": 0.00,
"taxes": [
{
"shortName": "IVA",
"taxableUnitCode": "1",
"taxableAmount": 89.29,
"taxAmount": 10.71
}
]
},
{
"name": "PROPINA",
"unitOfMeasure": "UNI",
"goodOrService": "S",
"quantity": 1,
"unitPrice": 10.00,
"amount": 10.00,
"discount": 0.00,
"taxes": []
}
],
"addendumData": {
"version": "7.1234654163",
"internalReference": "'"${SALE_ID}"'",
"dateReference": "2025-01-21T10:00:00.000Z",
"validateInternalReference": "VALIDAR"
},
"total": 110.00
}'
Note: The system automatically detects "PROPINA" in the item name and sets PropinaAdenda: "1" in the DTE JSON.
Invoice with CUI Identification
For customers identified by CUI instead of NIT:
curl -X POST "${BASE_URL}/fel/certify-document" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"businessData": {
"id": "'"${BUSINESS_ID}"'"
},
"felProviderData": {
"providerName": "rpafelapi"
},
"generalData": {
"type": "FACT",
"dateTimeIssue": "2025-01-21T10:00:00.000Z",
"currencyCode": "GTQ"
},
"issuerData": {
"taxId": "44653948",
"taxName": "COMPANY NAME, S.A.",
"establishmentCode": "1",
"commercialName": "COMPANY",
"vatAffiliationCode": "GEN",
"addressData": {
"address": "ADDRESS",
"postalCode": "01001",
"municipality": "Guatemala",
"department": "Guatemala",
"country": "GT"
}
},
"receiverData": {
"taxId": "2260269730101",
"taxName": "CUSTOMER NAME",
"taxpayerType": "CUI",
"addressData": {
"address": "ADDRESS",
"postalCode": "01001",
"municipality": "Guatemala",
"department": "Guatemala",
"country": "GT"
}
},
"phrases": [
{
"phraseType": "1",
"scenarioCode": "1"
}
],
"items": [
{
"name": "Product description",
"unitOfMeasure": "UNI",
"goodOrService": "B",
"quantity": 1,
"unitPrice": 100.00,
"amount": 100.00,
"discount": 0.00,
"taxes": [
{
"shortName": "IVA",
"taxableUnitCode": "1",
"taxableAmount": 89.29,
"taxAmount": 10.71
}
]
}
],
"addendumData": {
"version": "7.1234654163",
"internalReference": "'"${SALE_ID}"'",
"dateReference": "2025-01-21T10:00:00.000Z",
"validateInternalReference": "VALIDAR"
},
"total": 100.00
}'
Important:
- For regular NITs, do NOT set
taxpayerTypeor set it tonull/undefined. The system will omitTipoEspecialautomatically. - For CUI or other special identification types, set
taxpayerType: "CUI"(or "EXT", etc.) and the system will automatically setTipoEspecial: "CUI"in the DTE JSON. - Never set
taxpayerType: "NIT"- this causes validation errors because "NIT" is not a valid value forTipoEspecial.
Response Example
{
"Codigo": 0,
"Mensaje": "OK",
"AcuseReciboSAT": "A-1234567890",
"Autorizacion": "A-123456",
"Serie": "A",
"NUMERO": "123456",
"Fecha_DTE": "2025-01-21T10:00:00Z",
"Fecha_de_certificacion": "2025-01-21T10:00:00Z",
"NITCertificador": "12345678",
"NombreCertificador": "DIGIFACT S.A.",
"ResponseDATA1": "base64-xml-content"
}
2. Get Shared Info (NIT/CUI Lookup)
POST /fel/get-shared-info
Queries taxpayer information from RPAfelApi. This endpoint uses RPAfelApi's QueryPayerInfo endpoint.
Query by NIT
curl -X POST "${BASE_URL}/fel/get-shared-info" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"businessId": "'"${BUSINESS_ID}"'",
"data1": "SHARED_GETINFONITcom",
"data2": "NIT|49862952"
}'
Query by CUI
curl -X POST "${BASE_URL}/fel/get-shared-info" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"businessId": "'"${BUSINESS_ID}"'",
"data1": "SHARED_GETINFOCUI",
"data2": "CUI|2260269730101"
}'
Response Example
{
"Success": true,
"TaxPayerId": "49862952",
"TaxPayerName": "RANGEL,CASTRO,,KENNETH,ZAIDD",
"PersonalId": null
}
3. Create and Certify Credit Note (NCRE)
POST /fel/credit-notes
Creates a credit note (Nota de Crédito) that will be certified via RPAfelApi.
curl -X POST "${BASE_URL}/fel/credit-notes" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"businessId": "'"${BUSINESS_ID}"'",
"saleId": "'"${SALE_ID}"'",
"createdBy": "'"${USER_ID}"'",
"creditNoteDate": "2025-01-21T10:00:00.000Z",
"customerId": "'"${CUSTOMER_ID}"'",
"taxId": "49862952",
"taxName": "Cliente de Prueba",
"taxAddress": "Ciudad de Guatemala",
"locationId": "'"${LOCATION_ID}"'",
"locationName": "Tienda Principal",
"currencyId": "'"${CURRENCY_ID}"'",
"currencyCode": "GTQ",
"minorUnit": 2,
"exchangeRate": 1.0,
"currency": {
"id": "'"${CURRENCY_ID}"'",
"code": "GTQ",
"name": "Quetzal",
"symbol": "Q"
},
"totalAmount": 100.00,
"totalBaseAmount": 90.00,
"detail": {
"items": [
{
"productId": "product-uuid",
"productName": "Producto de Prueba",
"quantity": 1,
"unitPrice": 100.00,
"amount": 100.00,
"baseAmount": 90.00,
"taxes": [
{
"taxId": "tax-uuid",
"taxName": "IVA",
"rate": 0.12,
"amount": 10.00,
"baseAmount": 90.00
}
]
}
]
},
"paymentDetail": {},
"taxpayerType": "NIT",
"originalInvoiceUuid": "A-123456",
"adjustmentReason": "Devolución de mercancía",
"generateElectronicTaxDocument": true
}'
Response: Returns credit note object with id field.
Get Credit Note
curl -X GET "${BASE_URL}/fel/credit-notes/{credit-note-id}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json"
Get Credit Notes by Sale
curl -X GET "${BASE_URL}/fel/credit-notes/sale/${SALE_ID}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json"
Certify Credit Note
curl -X POST "${BASE_URL}/fel/credit-notes/{credit-note-id}/certify" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json"
Note: This endpoint:
- Validates SAT requirements
- Converts to DTE JSON (NCRE type)
- Sends to RPAfelApi via
generateCertificateToSign - Updates credit note with certification details
- Triggers inventory reversal event
4. Create and Certify Debit Note (NDEB)
POST /fel/debit-notes
Creates a debit note (Nota de Débito) that will be certified via RPAfelApi.
curl -X POST "${BASE_URL}/fel/debit-notes" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"businessId": "'"${BUSINESS_ID}"'",
"saleId": "'"${SALE_ID}"'",
"createdBy": "'"${USER_ID}"'",
"debitNoteDate": "2025-01-21T10:00:00.000Z",
"customerId": "'"${CUSTOMER_ID}"'",
"taxId": "49862952",
"taxName": "Cliente de Prueba",
"taxAddress": "Ciudad de Guatemala",
"locationId": "'"${LOCATION_ID}"'",
"locationName": "Tienda Principal",
"currencyId": "'"${CURRENCY_ID}"'",
"currencyCode": "GTQ",
"minorUnit": 2,
"exchangeRate": 1.0,
"currency": {
"id": "'"${CURRENCY_ID}"'",
"code": "GTQ",
"name": "Quetzal",
"symbol": "Q"
},
"totalAmount": 50.00,
"totalBaseAmount": 45.00,
"detail": {
"items": [
{
"productId": "product-uuid",
"productName": "Producto de Prueba",
"quantity": 1,
"unitPrice": 50.00,
"amount": 50.00,
"baseAmount": 45.00,
"taxes": [
{
"taxId": "tax-uuid",
"taxName": "IVA",
"rate": 0.12,
"amount": 5.00,
"baseAmount": 45.00
}
]
}
]
},
"paymentDetail": {},
"taxpayerType": "NIT",
"originalInvoiceUuid": "A-123456",
"adjustmentReason": "Ajuste por error en facturación",
"generateElectronicTaxDocument": true
}'
Get Debit Note
curl -X GET "${BASE_URL}/fel/debit-notes/{debit-note-id}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json"
Get Debit Notes by Sale
curl -X GET "${BASE_URL}/fel/debit-notes/sale/${SALE_ID}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json"
Certify Debit Note
curl -X POST "${BASE_URL}/fel/debit-notes/{debit-note-id}/certify" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json"
Note: This endpoint:
- Validates SAT requirements
- Converts to DTE JSON (NDEB type)
- Sends to RPAfelApi via
generateCertificateToSign - Updates debit note with certification details
5. Request and Certify Cancellation (ANULACION)
POST /fel/cancellations
Requests cancellation of an invoice. This will be certified via RPAfelApi.
curl -X POST "${BASE_URL}/fel/cancellations" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"saleId": "'"${SALE_ID}"'",
"cancellationReason": "Error en la facturación",
"createdBy": "'"${USER_ID}"'"
}'
Response: Returns cancellation object with id field.
Important: Cancellation can only be requested for invoices in the same month they were issued (SAT requirement).
Get Cancellation
curl -X GET "${BASE_URL}/fel/cancellations/{cancellation-id}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json"
Get Cancellations by Sale
curl -X GET "${BASE_URL}/fel/cancellations/sale/${SALE_ID}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json"
Certify Cancellation
curl -X POST "${BASE_URL}/fel/cancellations/{cancellation-id}/certify" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json"
Note: This endpoint:
- Validates SAT requirements (same-month cancellation)
- Converts to DTE JSON (ANULACION type)
- Sends to RPAfelApi via
generateCertificateToSign - Updates cancellation with certification details
- Updates sale status to
CANCELLED - Triggers inventory reversal event
6. Convert Invoice to XML (Testing/Debugging)
POST /fel/convert-to-xml
Converts an Invoice document to XML format. Useful for testing and debugging.
curl -X POST "${BASE_URL}/fel/convert-to-xml" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"businessData": {
"id": "'"${BUSINESS_ID}"'"
},
"felProviderData": {
"providerName": "rpafelapi"
},
"generalData": {
"type": "FACT",
"dateTimeIssue": "2025-01-21T10:00:00.000Z",
"currencyCode": "GTQ"
},
"issuerData": {
"taxId": "44653948",
"taxName": "LA LECHITA, SOCIEDAD ANONIMA",
"establishmentCode": "1",
"commercialName": "TUSA",
"vatAffiliationCode": "GEN",
"addressData": {
"address": "KM 55.5 CARRETERA INTERAMERICANA",
"postalCode": "04001",
"municipality": "Chimaltenango",
"department": "Chimaltenango",
"country": "GT"
}
},
"receiverData": {
"taxId": "CF",
"taxName": "CONSUMIDOR FINAL",
"addressData": {
"address": "CIUDAD",
"postalCode": "01010",
"municipality": "GUATEMALA",
"department": "GUATEMALA",
"country": "GT"
}
},
"phrases": [
{
"phraseType": "1",
"scenarioCode": "1"
}
],
"items": [
{
"name": "Product 1",
"unitOfMeasure": "UNI",
"goodOrService": "B",
"quantity": 2,
"unitPrice": 20.00,
"amount": 40.00,
"discount": 0.00,
"taxes": [
{
"shortName": "IVA",
"taxableUnitCode": "1",
"taxableAmount": 35.714285,
"taxAmount": 4.285714
}
]
}
],
"addendumData": {
"version": "7.1234654163",
"internalReference": "'"${SALE_ID}"'",
"dateReference": "2025-01-21T10:00:00.000Z",
"validateInternalReference": "VALIDAR"
},
"total": 40.00
}'
Response: XML content (Content-Type: application/xml)
Complete Workflow Examples
Invoice Certification Flow
#!/bin/bash
# 1. Certify invoice
RESPONSE=$(curl -s -X POST "${BASE_URL}/fel/certify-document" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d @invoice.json)
# Extract authorization number
AUTORIZACION=$(echo "$RESPONSE" | jq -r '.Autorizacion')
echo "Invoice certified: $AUTORIZACION"
# 2. Query payer info
curl -X POST "${BASE_URL}/fel/get-shared-info" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"businessId": "'"${BUSINESS_ID}"'",
"data1": "SHARED_GETINFONITcom",
"data2": "NIT|49862952"
}'
Credit Note Flow
#!/bin/bash
# 1. Create credit note
CREDIT_NOTE_RESPONSE=$(curl -s -X POST "${BASE_URL}/fel/credit-notes" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d @credit-note.json)
CREDIT_NOTE_ID=$(echo "$CREDIT_NOTE_RESPONSE" | jq -r '.id')
echo "Credit note created: $CREDIT_NOTE_ID"
# 2. Get credit note
curl -X GET "${BASE_URL}/fel/credit-notes/${CREDIT_NOTE_ID}" \
-H "Authorization: Bearer ${TOKEN}"
# 3. Certify credit note
CERT_RESPONSE=$(curl -s -X POST "${BASE_URL}/fel/credit-notes/${CREDIT_NOTE_ID}/certify" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json")
AUTORIZACION=$(echo "$CERT_RESPONSE" | jq -r '.Autorizacion')
echo "Credit note certified: $AUTORIZACION"
Cancellation Flow
#!/bin/bash
# 1. Request cancellation
CANCELLATION_RESPONSE=$(curl -s -X POST "${BASE_URL}/fel/cancellations" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"saleId": "'"${SALE_ID}"'",
"cancellationReason": "Error en la facturación",
"createdBy": "'"${USER_ID}"'"
}')
CANCELLATION_ID=$(echo "$CANCELLATION_RESPONSE" | jq -r '.id')
echo "Cancellation requested: $CANCELLATION_ID"
# 2. Certify cancellation
CERT_RESPONSE=$(curl -s -X POST "${BASE_URL}/fel/cancellations/${CANCELLATION_ID}/certify" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json")
AUTORIZACION=$(echo "$CERT_RESPONSE" | jq -r '.Autorizacion')
echo "Cancellation certified: $AUTORIZACION"
Quick Reference Table
| Endpoint | Method | Uses RPAfelApi | Description |
|---|---|---|---|
/fel/certify-document | POST | ✅ Yes | Certify invoice (FACT) |
/fel/get-shared-info | POST | ✅ Yes | Query NIT/CUI info |
/fel/credit-notes | POST | ❌ No* | Create credit note |
/fel/credit-notes/:id/certify | POST | ✅ Yes | Certify credit note (NCRE) |
/fel/debit-notes | POST | ❌ No* | Create debit note |
/fel/debit-notes/:id/certify | POST | ✅ Yes | Certify debit note (NDEB) |
/fel/cancellations | POST | ❌ No* | Request cancellation |
/fel/cancellations/:id/certify | POST | ✅ Yes | Certify cancellation (ANULACION) |
/fel/convert-to-xml | POST | ❌ No | Convert to XML (testing) |
* These endpoints create records in the database but don't call RPAfelApi until certification.
RPAfelApi Features Used
Automatic Features
- Token Caching: Tokens are automatically cached and refreshed
- Retry Logic: Automatic retry with exponential backoff on transient failures
- Tip Detection: Automatically detects "PROPINA" items and sets
PropinaAdenda: "1" - CUI Support: Automatically handles CUI identification via
taxpayerType: "CUI" - Special NIT Handling: Framework for special NIT phrase handling
- Error Handling: Enhanced error handling with detailed logging
RPAfelApi Endpoints Called
POST /api/fel/GetToken- Get authentication token (cached)POST /api/fel/generateCertificateToSign- Certify documentsPOST /api/fel/QueryPayerInfo- Query taxpayer information
Error Handling
Common HTTP Status Codes
- 200 OK - Request successful
- 400 Bad Request - Invalid request data
- 401 Unauthorized - Invalid or missing token
- 406 Not Acceptable - Document already signed (RPAfelApi handles automatically)
- 500 Internal Server Error - Server error
Error Response Format
{
"statusCode": 400,
"message": "Error message description",
"error": "Bad Request"
}
Retry Behavior
The backend automatically retries on:
- 401 Unauthorized (token refresh)
- 406 Not Acceptable (already signed)
- 5xx Server errors
Retries are not performed on:
- 400 Bad Request (client error)
- 403 Forbidden (authorization error)
Notes
-
Authentication: All endpoints require
Authorization: Bearer <token>header -
Business Config: FEL credentials are stored in
business.felCertifierConfig -
Provider Selection: Set
felProviderData.providerName: "rpafelapi"to use RPAfelApi -
UUID Format: Use actual UUIDs from your database
-
Date Format: Use ISO 8601 format:
2025-01-21T10:00:00.000Z -
Currency: Use
GTQfor Guatemalan Quetzal -
Document Types:
FACT- InvoiceNCRE- Credit NoteNDEB- Debit NoteANULACION- Cancellation
-
TipoEspecial Handling:
- Do NOT set
taxpayerType: "NIT"- this causes validation errors - For regular NITs, omit
taxpayerTypeor set it tonull - For special types (CUI, EXT, etc.), set
taxpayerType: "CUI"(or appropriate value) - The system automatically includes
TipoEspecialonly for valid special types
- Do NOT set
Testing Tips
-
Use jq for JSON parsing:
echo "$RESPONSE" | jq '.' -
Save responses to files:
curl ... > response.json -
Verbose output for debugging:
curl -v -X POST ... -
Check HTTP status:
curl -w "\nHTTP Status: %{http_code}\n" ...
Last Updated: 2025-01-21
Maintained By: FEL Team