Examples by country
✅ Recommended practices
1. Manage access_token efficiently
It's crucial to manage the access_token obtained from /auth efficiently to avoid rate limiting and IP bans. This is especially important when processing high volumes of documents.
Best practice: Store the access_token for 60 minutes and reuse it for all subsequent document issuances. Do not request a new token for each document creation.
Example: Token management
// Request to /auth endpoint
POST https://api-billing.koywe.com/V1/auth
Content-Type: application/json
{
"grant_type": "password",
"client_id": "your_client_id",
"client_secret": "your_client_secret",
"username": "your_username",
"password": "your_password"
}
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
Implementation recommendation:
- Cache the
access_tokenwith a TTL of 60 minutes (3600 seconds) - Reuse the same token for all API calls within this period
- Only request a new token when the current one expires or is about to expire
- This prevents excessive authentication requests that could trigger rate limiting on your IP
2. IP whitelisting (for high volumes)
If your system processes more than 5 documents per second, you should provide us your IP addresses for whitelisting to prevent potential blocks.
Why this is important:
- High-volume traffic may trigger security measures
- Whitelisting ensures your IPs are not blocked
- Contact support to add your IPs to the whitelist
Action required: Contact your sales representative with:
- Your production IP addresses
- Expected volume (documents per second)
- Account information
3. Respect rate limits and handle 429 errors
Always respect the rate limits defined in your contract. If you exceed the rate limit, you will receive a 429 Too Many Requests error.
Best practices:
- Monitor your request rate: Do not exceed the rate limit specified in your contract
- Implement exponential backoff: When receiving a
429error, wait at least 30 seconds before retrying - Handle retries gracefully: Implement a retry mechanism with proper delays
Example: Handling 429 errors
// Error response when rate limit is exceeded
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Implementation recommendation:
# Pseudo-code example
def create_document_with_retry(document_data, access_token):
max_retries = 3
backoff_seconds = 30
for attempt in range(max_retries):
try:
response = post_document(document_data, access_token)
return response
except HTTPError as e:
if e.status_code == 429:
if attempt < max_retries - 1:
time.sleep(backoff_seconds)
continue
else:
raise Exception("Rate limit exceeded after retries")
else:
raise
4. Prevent duplicates using reference field
To avoid duplicate document creation when retrying requests, use the reference field with reference_type 802 (Nota de pedido) containing your internal transaction ID.
Sending a document with reference
When creating a document, include the references array with your internal transaction ID:
{
"header": {
"account_id": 423,
"document_type_id": "2",
"received_issued_flag": 1,
"issue_date": "2025-01-07",
"issuer_tax_id_code": "76399932-7",
"issuer_tax_id_type": "CL-RUT",
"issuer_legal_name": "Your Company Name",
"issuer_address": "Your Address",
"issuer_district": "Your District",
"issuer_city": "Your City",
"issuer_country_id": "253",
"issuer_phone": "Your Phone",
"issuer_activity": "Your Activity",
"receiver_tax_id_code": "76399932-7",
"receiver_tax_id_type": "CL-RUT",
"receiver_legal_name": "Receiver Name",
"receiver_address": "Receiver Address",
"receiver_district": "Receiver District",
"receiver_city": "Receiver City",
"receiver_country_id": "253",
"receiver_phone": "Receiver Phone",
"receiver_activity": "Receiver Activity",
"payment_conditions": "0",
"currency_id": 39
},
"details": [
{
"quantity": 1,
"sku": "SKU001",
"line_description": "Product Description",
"unit_measure": "UN",
"unit_price": 1500,
"long_description": "Detailed description",
"modifier_amount": 0,
"total_taxes": 285,
"modifier_percentage": 0,
"total_amount_line": 1785,
"taxes": [
{
"tax_type_id": "387",
"tax_percentage": 19,
"tax_amount": 285
}
]
}
],
"references": [
{
"reference_type": 802,
"reference_number": "TXN-2025-001234",
"reference_code": 5,
"description": "Internal transaction ID"
}
],
"totals": {
"net_amount": 1500,
"taxes_amount": 285,
"total_amount": 1785
}
}
Key points:
reference_type: 802 (Nota de pedido) - used for non-tax document referencesreference_number: Your internal transaction ID (e.g., "TXN-2025-001234")reference_code: 5 (reference to other non-tax documents)
Searching documents by reference
To check if a document with a specific reference already exists, use the GET /documents endpoint with query parameters:
Endpoint: GET https://api-billing.koywe.com/V1/documents
Query parameters:
reference_type:802(to filter by reference type)reference_number: Your internal transaction ID (e.g.,TXN-2025-001234)
Example request:
GET https://api-billing.koywe.com/V1/documents?reference_type=802&reference_number=TXN-2025-001234
Authorization: Bearer <your_access_token>
Accept: */*
Example response:
{
"data": [
{
"document_id": 12345,
"header": {
"document_number": "F001-000123",
"issue_date": "2025-01-07",
...
},
"references": [
{
"reference_type": 802,
"reference_number": "TXN-2025-001234",
"reference_code": 5,
"description": "Internal transaction ID"
}
],
...
}
],
"pagination": {
"total": 1,
"per_page": 20,
"current_page": 1
}
}
Implementation recommendation when you are retrying to issue:
- Before creating a document, check if a document with your internal transaction ID already exists (DO NOT include this validation on every common issuance or you will face performance issues)
- If found, use the existing
document_idinstead of creating a duplicate - If not found, proceed with document creation including the reference field
- This ensures idempotency and prevents duplicate documents
Note: Summary: Follow these best practices for reliable document issuance: cache your access token, whitelist your IPs (if processing high volumes), respect rate limits with proper backoff, and use reference fields to prevent duplicates.