Error Handling Best Practices
Learn how to handle errors gracefully when using the Kynode API.
Error response format
Error payloads are JSON objects intended for both machines and humans. They typically include a stable machine code, a short message, a documentation link, and a suggested remediation:
{
"error": "INVALID_API_KEY",
"message": "API key is invalid or expired",
"docs_url": "https://kynode.dev/docs/api-reference#authentication",
"solution": "Generate a new API key from your dashboard"
}Error code reference
| Error code | Description | What to do |
|---|---|---|
| INVALID_API_KEY | API key is invalid or expired. | Create a new key in the dashboard and rotate your configuration. |
| INVALID_BUSINESS_NUMBER | The business number does not match the expected format. | Normalize input to the `123-45-67890` pattern before calling the API. |
| RATE_LIMIT_EXCEEDED | Too many requests in the current window. | Apply exponential backoff and cache results where possible. |
| BUSINESS_NOT_FOUND | No registration matches the supplied number. | Confirm the number with the counterparty; the business may be closed or mistyped. |
| TIMEOUT | The upstream registry did not respond in time. | Retry with backoff; fail gracefully in UX if retries are exhausted. |
| SERVER_ERROR | An unexpected failure occurred on the service side. | Retry later; if the problem persists, check status and documentation. |
Retry logic implementation
Retry only idempotent read operations and only for transient codes such as rate limits or timeouts. Do not blindly retry on `INVALID_BUSINESS_NUMBER`.
JavaScript
async function verifyWithRetry(maxRetries = 3) {
const payload = {
business_number: '8090903407',
startDate: '20240101',
ownerName: '강민구',
company_name: '노드메트릭스',
language: 'en',
};
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch('https://kynode-api.kynode.workers.dev/v1/verify', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KYNODE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
if (response.status === 429) {
const delay = Math.pow(2, i) * 1000;
await new Promise((resolve) => setTimeout(resolve, delay));
continue;
}
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
} catch (error) {
if (i === maxRetries - 1) throw error;
}
}
throw new Error('Max retries exceeded');
}Python
import time
import requests
def verify_with_retry(max_retries=3):
payload = {
'business_number': '8090903407',
'startDate': '20240101',
'ownerName': '강민구',
'company_name': '노드메트릭스',
'language': 'en',
}
headers = {'Authorization': f'Bearer {KYNODE_KEY}'}
for attempt in range(max_retries):
response = requests.post(
'https://kynode-api.kynode.workers.dev/v1/verify',
headers=headers,
json=payload,
timeout=30,
)
if response.status_code == 429 and attempt < max_retries - 1:
time.sleep(2 ** attempt)
continue
response.raise_for_status()
return response.json()
raise RuntimeError('Max retries exceeded')Logging best practices
Log the error code, request ID if provided, and a hash of the business number—never full API keys or raw PII in application logs.
Correlate client-side user actions with server logs using a stable trace ID you generate per verification flow.
Error monitoring and alerting
Track error rates by code in your APM or metrics stack; alert when `SERVER_ERROR` or timeout rates spike above a baseline.
Dashboard usage charts help verify whether throttling correlates with specific deploys or customers.