API Overview
Credit Device integrates with the CreditDevice platform via a modern REST API. This guide provides a technical overview of the API architecture and endpoints.
API Architecture
Base Configuration
Base URL: https://api.creditdevice.com/v1/
Protocol: HTTPS only (TLS 1.2+)
Authentication: API Key (Bearer token)
Content-Type: application/json
Response Format: JSONAuthentication
API Key Header:
Authorization: Bearer cd_ak_1a2b3c4d5e6f7g8h9i0j
X-Client-ID: business-central-integration
X-API-Version: 1.0Request Signing (Optional):
X-Signature: SHA256=base64(hmac_sha256(secret, request_body))
X-Timestamp: 1679414400
X-Nonce: random_string_12345Core Endpoints
1. Health Check
Endpoint: GET /health
Purpose: Verificeer API beschikbaarheid en status
Request:
GET https://api.creditdevice.com/v1/health
Authorization: Bearer {api_key}Response:
{
"status": "healthy",
"timestamp": "2026-03-21T10:30:00Z",
"version": "1.2.3",
"services": {
"database": "healthy",
"authentication": "healthy",
"webhooks": "healthy"
},
"rate_limits": {
"requests_per_minute": 60,
"current_usage": 15
}
}2. Customer/Debtor Management
Import Customers
Endpoint: POST /customers/import
Purpose: Bulk import van Business Central klanten naar CreditDevice
Request:
POST https://api.creditdevice.com/v1/customers/import
Content-Type: application/json
Authorization: Bearer {api_key}
{
"batch_id": "bc_import_20260321_103000",
"source": "business_central",
"customers": [
{
"customer_id": "CUST001",
"name": "Acme Corporation B.V.",
"email": "finance@acme.nl",
"phone": "+31 20 1234567",
"address": {
"street": "Hoofdstraat 123",
"city": "Amsterdam",
"postal_code": "1000 AA",
"country": "NL"
},
"financial_info": {
"credit_limit": 50000.00,
"currency": "EUR",
"payment_terms": "30",
"risk_category": "LOW"
},
"metadata": {
"bc_last_modified": "2026-03-21T09:45:00Z",
"sync_version": "1.0"
}
}
]
}Response:
{
"batch_id": "bc_import_20260321_103000",
"status": "success",
"processed_at": "2026-03-21T10:30:15Z",
"results": {
"total_submitted": 150,
"successful": 147,
"failed": 3,
"warnings": 5
},
"errors": [
{
"customer_id": "CUST999",
"error_code": "INVALID_EMAIL",
"message": "Email format is invalid"
}
],
"next_actions": {
"retry_url": "/customers/import/retry/bc_import_20260321_103000",
"status_url": "/imports/status/bc_import_20260321_103000"
}
}Export Customers
Endpoint: GET /customers/export
Purpose: Export customer data van CreditDevice naar Business Central
Request:
GET https://api.creditdevice.com/v1/customers/export?modified_since=2026-03-20T00:00:00Z&limit=500
Authorization: Bearer {api_key}Response:
{
"export_id": "exp_20260321_103000",
"generated_at": "2026-03-21T10:30:00Z",
"pagination": {
"total_records": 1250,
"current_page": 1,
"per_page": 500,
"has_next": true,
"next_url": "/customers/export?page=2&modified_since=2026-03-20T00:00:00Z"
},
"customers": [
{
"customer_id": "CUST001",
"name": "Updated Company Name B.V.",
"credit_assessment": {
"score": 750,
"rating": "A",
"last_updated": "2026-03-21T08:15:00Z",
"risk_indicators": []
},
"financial_summary": {
"total_exposure": 25000.00,
"overdue_amount": 0.00,
"days_sales_outstanding": 25
}
}
]
}3. Invoice Management
Import Invoices
Endpoint: POST /invoices/import
Request:
{
"batch_id": "bc_inv_20260321_103000",
"invoices": [
{
"invoice_number": "INV-2026-00001",
"customer_id": "CUST001",
"invoice_date": "2026-03-15",
"due_date": "2026-04-14",
"amount": {
"subtotal": 1000.00,
"tax_amount": 210.00,
"total_amount": 1210.00,
"currency": "EUR"
},
"payment_status": "open",
"line_items": [
{
"item_code": "SERV001",
"description": "Consulting Services",
"quantity": 10,
"unit_price": 100.00,
"line_total": 1000.00
}
]
}
]
}Payment Updates
Endpoint: PUT /invoices/{invoice_id}/payments
Purpose: Update payment status van facturen
Request:
{
"payment_id": "PAY-2026-00001",
"payment_date": "2026-03-21",
"amount_paid": 1210.00,
"payment_method": "bank_transfer",
"reference": "TRF202603210001",
"status": "completed"
}Webhook Integration
Webhook Configuration
Registratie via API:
POST https://api.creditdevice.com/v1/webhooks
Content-Type: application/json
Authorization: Bearer {api_key}
{
"url": "https://yourtenant.businesscentral.dynamics.com/webhook/creditdevice",
"events": [
"customer.updated",
"invoice.payment_received",
"credit_assessment.completed"
],
"secret": "webhook_secret_key_12345",
"active": true
}Webhook Events
Customer Updated Event
Event: customer.updated
Payload:
{
"event": "customer.updated",
"timestamp": "2026-03-21T10:30:00Z",
"webhook_id": "wh_123456789",
"data": {
"customer_id": "CUST001",
"changes": {
"credit_limit": {
"old_value": 50000.00,
"new_value": 75000.00
},
"risk_category": {
"old_value": "MEDIUM",
"new_value": "LOW"
}
},
"updated_at": "2026-03-21T10:29:45Z"
}
}Payment Received Event
Event: invoice.payment_received
Payload:
{
"event": "invoice.payment_received",
"timestamp": "2026-03-21T10:30:00Z",
"data": {
"invoice_number": "INV-2026-00001",
"customer_id": "CUST001",
"payment": {
"amount": 1210.00,
"currency": "EUR",
"payment_date": "2026-03-21",
"method": "bank_transfer",
"reference": "TRF202603210001"
},
"invoice_status": "paid",
"remaining_balance": 0.00
}
}Rate Limiting
Standard Limits
Requests per minute: 60
Requests per hour: 3,600
Burst capacity: 120 requests (2 minute window)
Daily volume: 100,000 requestsRate Limit Headers
Response Headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1679414460
X-RateLimit-Retry-After: 30Rate Limit Exceeded Response:
{
"error": "rate_limit_exceeded",
"message": "Too many requests. Please retry after 30 seconds.",
"retry_after": 30,
"limits": {
"requests_per_minute": 60,
"current_usage": 61
}
}Error Handling
Standard HTTP Status Codes
| Status Code | Betekenis | Actie |
|---|---|---|
| 200 | Success | Continue |
| 201 | Created | Resource created successfully |
| 400 | Bad Request | Fix request format |
| 401 | Unauthorized | Check API key |
| 403 | Forbidden | Verify permissions |
| 404 | Not Found | Check endpoint URL |
| 429 | Rate Limited | Implement backoff |
| 500 | Server Error | Retry after delay |
| 503 | Service Unavailable | Check service status |
Error Response Format
{
"error": "validation_failed",
"message": "Request validation failed",
"timestamp": "2026-03-21T10:30:00Z",
"request_id": "req_123456789",
"details": [
{
"field": "customer.email",
"code": "invalid_format",
"message": "Email address format is invalid"
}
],
"help_url": "https://docs.creditdevice.com/errors/validation_failed"
}Business Central Implementation
API Client Codeunit
codeunit 11195979 "QTEAM REST Web service Mgt"
{
procedure SendRequest(Method: Text; Endpoint: Text; RequestBody: Text; var ResponseBody: Text): Boolean
var
HttpClient: HttpClient;
HttpRequestMessage: HttpRequestMessage;
HttpResponseMessage: HttpResponseMessage;
HttpHeaders: HttpHeaders;
HttpContent: HttpContent;
Setup: Record "QTEAM Credit Device Setup";
begin
Setup.Get();
// Configure request
HttpRequestMessage.Method := Method;
HttpRequestMessage.SetRequestUri(Setup."Base URL" + Endpoint);
// Set headers
HttpHeaders := HttpRequestMessage.GetHeaders();
HttpHeaders.Add('Authorization', 'Bearer ' + Setup."API Key");
HttpHeaders.Add('Content-Type', 'application/json');
HttpHeaders.Add('X-Client-ID', 'business-central-integration');
// Set body for POST/PUT
if RequestBody <> '' then begin
HttpContent.WriteFrom(RequestBody);
HttpRequestMessage.Content := HttpContent;
end;
// Send request
if HttpClient.Send(HttpRequestMessage, HttpResponseMessage) then begin
HttpResponseMessage.Content.ReadAs(ResponseBody);
exit(HttpResponseMessage.IsSuccessStatusCode());
end;
exit(false);
end;
}Retry Logic Implementation
procedure SendWithRetry(Method: Text; Endpoint: Text; RequestBody: Text; var ResponseBody: Text): Boolean
var
Attempt: Integer;
Success: Boolean;
DelayMs: Integer;
begin
DelayMs := 1000; // Start with 1 second
for Attempt := 1 to 3 do begin
Success := SendRequest(Method, Endpoint, RequestBody, ResponseBody);
if Success then
exit(true);
// Exponential backoff
Sleep(DelayMs);
DelayMs := DelayMs * 2;
end;
exit(false);
end;Webhook Handler
procedure ProcessWebhookEvent(EventType: Text; Payload: Text)
var
JsonMgt: Codeunit "QTEAM JSON Methods";
CustomerMgt: Codeunit "QTEAM Credit Device Mgt";
begin
case EventType of
'customer.updated':
CustomerMgt.ProcessCustomerUpdate(Payload);
'invoice.payment_received':
CustomerMgt.ProcessPaymentUpdate(Payload);
'credit_assessment.completed':
CustomerMgt.ProcessCreditAssessment(Payload);
end;
end;Testing en Development
Sandbox Environment
Sandbox Base URL: https://sandbox-api.creditdevice.com/v1/
Test API Keys: Beschikbaar via developer portal
Webhook Testing: Ngrok of similar tunneling service
Mock Data: Sample datasets availableAPI Testing Tools
Postman Collection: - Pre-configured requests - Environment variables - Test scripts - Documentation
AL Unit Tests:
codeunit 50100 "Credit Device API Tests"
{
[Test]
procedure TestHealthEndpoint()
var
RestMgt: Codeunit "QTEAM REST Web service Mgt";
Response: Text;
begin
Assert.IsTrue(
RestMgt.SendRequest('GET', 'health', '', Response),
'Health endpoint should respond successfully'
);
end;
}Monitoring en Analytics
API Metrics
{
"api_metrics": {
"requests_per_minute": 45,
"average_response_time": 250,
"error_rate": 0.02,
"uptime_percentage": 99.9
},
"endpoint_performance": {
"/customers/import": {
"avg_response_time": 2500,
"success_rate": 98.5
},
"/invoices/export": {
"avg_response_time": 1200,
"success_rate": 99.2
}
}
}Application Insights Integration
procedure LogAPICall(Endpoint: Text; ResponseTime: Integer; Success: Boolean)
var
TelemetryMgt: Codeunit "Telemetry Management";
CustomDimensions: Dictionary of [Text, Text];
begin
CustomDimensions.Add('endpoint', Endpoint);
CustomDimensions.Add('response_time_ms', Format(ResponseTime));
CustomDimensions.Add('success', Format(Success));
TelemetryMgt.LogMessage(
'Credit Device API Call',
'API request completed',
Verbosity::Normal,
DataClassification::SystemMetadata,
TelemetryScope::All,
CustomDimensions
);
end;