✅ 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

1// Request to /auth endpoint
2POST https://api-billing.koywe.com/V1/auth
3Content-Type: application/json
4
5{
6 "grant_type": "password",
7 "client_id": "your_client_id",
8 "client_secret": "your_client_secret",
9 "username": "your_username",
10 "password": "your_password"
11}

Response:

1{
2 "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
3 "token_type": "Bearer",
4 "expires_in": 3600
5}

Implementation recommendation:

  • Cache the access_token with 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:

  1. Monitor your request rate: Do not exceed the rate limit specified in your contract
  2. Implement exponential backoff: When receiving a 429 error, wait at least 30 seconds before retrying
  3. Handle retries gracefully: Implement a retry mechanism with proper delays

Example: Handling 429 errors

1// Error response when rate limit is exceeded
2HTTP/1.1 429 Too Many Requests
3Content-Type: application/json

Implementation recommendation:

1# Pseudo-code example
2def create_document_with_retry(document_data, access_token):
3 max_retries = 3
4 backoff_seconds = 30
5
6 for attempt in range(max_retries):
7 try:
8 response = post_document(document_data, access_token)
9 return response
10 except HTTPError as e:
11 if e.status_code == 429:
12 if attempt < max_retries - 1:
13 time.sleep(backoff_seconds)
14 continue
15 else:
16 raise Exception("Rate limit exceeded after retries")
17 else:
18 raise

4. Prevent duplicates using reference field

To avoid duplicate document creation when retrying requests, use the reference field with reference_code 5 (reference to other non-tax documents) containing your internal transaction ID.

Sending a document with reference

When creating a document, include the references array with your internal transaction ID:

1{
2 "header": {
3 "account_id": 14540,
4 "document_type_id": "82",
5 "received_issued_flag": 0,
6 "issue_date": "2025-01-14",
7 "issuer_tax_id_code": "860517022-2",
8 "issuer_tax_id_type": "CO-NIT",
9 "issuer_legal_name": "Your Company Name",
10 "issuer_address": "Your Address",
11 "issuer_district": "Your District",
12 "issuer_city": "Your City",
13 "issuer_country_id": "66",
14 "issuer_phone": "Your Phone",
15 "issuer_activity": "Your Activity",
16 "receiver_tax_id_code": "860517022-2",
17 "receiver_tax_id_type": "CO-NIT",
18 "receiver_legal_name": "Receiver Name",
19 "receiver_address": "Receiver Address",
20 "receiver_county_id": "496",
21 "receiver_country_id": "66",
22 "receiver_phone": "Receiver Phone",
23 "receiver_activity": "Receiver Activity",
24 "payment_conditions": "0",
25 "currency_id": 28
26 },
27 "details": [
28 {
29 "quantity": 1,
30 "line_description": "Product Description",
31 "unit_measure": "UN",
32 "unit_price": 1500,
33 "long_description": "Detailed description",
34 "modifier_amount": -100,
35 "total_taxes": 266,
36 "modifier_percentage": 0,
37 "total_amount_line": 1666,
38 "taxes": [
39 {
40 "tax_type_id": "388",
41 "tax_percentage": 19,
42 "tax_amount": 266
43 }
44 ]
45 }
46 ],
47 "references": [
48 {
49 "reference_number": "TXN-2025-001234",
50 "reference_code": 5,
51 "description": "Internal transaction ID"
52 }
53 ],
54 "totals": {
55 "net_amount": 1400,
56 "taxes_amount": 266,
57 "total_amount": 1666
58 }
59}

Key points:

  • reference_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_code: 5 (to filter by reference code)
  • reference_number: Your internal transaction ID (e.g., TXN-2025-001234)

Example request:

$GET https://api-billing.koywe.com/V1/documents?reference_code=5&reference_number=TXN-2025-001234
>Authorization: Bearer <your_access_token>
>Accept: */*

Example response:

1{
2 "data": [
3 {
4 "document_id": 12345,
5 "header": {
6 "document_number": "FV-2025-001234",
7 "issue_date": "2025-01-14",
8 ...
9 },
10 "references": [
11 {
12 "reference_number": "TXN-2025-001234",
13 "reference_code": 5,
14 "description": "Internal transaction ID"
15 }
16 ],
17 ...
18 }
19 ],
20 "pagination": {
21 "total": 1,
22 "per_page": 20,
23 "current_page": 1
24 }
25}

Implementation recommendation when you are retrying to issue:

  1. 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)
  2. If found, use the existing document_id instead of creating a duplicate
  3. If not found, proceed with document creation including the reference field
  4. This ensures idempotency and prevents duplicate documents

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.