ExecuteRestApiCommand
Execute HTTP REST API calls to external services from within your business process workflows. This command provides a flexible way to integrate with third-party APIs, microservices, and external systems.
Overview
ExecuteRestApiCommand allows you to make HTTP requests (GET, POST, PUT, PATCH, DELETE) to any REST API endpoint. It supports custom headers, authentication, request bodies, and returns the full response for further processing in your workflow.
Key Features
- Multiple HTTP Methods: Supports GET, POST, PUT, PATCH, and DELETE
- Custom Headers: Add any number of custom HTTP headers
- Authentication Support: Built-in authorization header support
- Flexible Content Types: Support for JSON, XML, form data, and other content types
- Response Handling: Returns full response including status code, headers, and body
- Error Handling: Graceful error handling with detailed error messages
- Logging: Automatic logging of requests and responses for debugging
Common Use Cases
- Calling external payment gateways
- Integrating with third-party KYC/AML services
- Sending data to webhooks
- Fetching data from external APIs
- Triggering microservices
- Posting to notification services
- Integrating with CRM systems
Syntax
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/endpoint',
method: 'POST',
headers: [
{ key: 'Content-Type', value: 'application/json' },
{ key: 'X-Custom-Header', value: 'custom-value' }
],
body: JSON.stringify({ key: 'value' }),
contentType: 'application/json',
authorizationHeader: 'Bearer your-token-here'
}
});
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The full URL of the API endpoint to call |
method | string | No | HTTP method: GET, POST, PUT, PATCH, DELETE (default: POST) |
headers | array | No | Array of header objects with key and value properties |
body | string | No | Request body as a string (ignored for GET requests) |
contentType | string | No | Content-Type for the request body (default: application/json) |
authorizationHeader | string | No | Authorization header value (e.g., "Bearer token") |
Headers Array Format
Headers must be provided as an array of objects:
headers: [
{ key: 'Header-Name', value: 'header-value' },
{ key: 'Another-Header', value: 'another-value' }
]
Return Value
The command returns a CommandExecutionResponse object:
{
IsSuccessful: true, // true if HTTP status code is 2xx
StatusCode: "200", // HTTP status code as string
Message: "OK", // HTTP status message
Data: "response body content" // Response body as string
}
Examples
Example 1: Simple GET Request
Fetch data from an external API:
// Get user data from external service
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/users/12345',
method: 'GET',
headers: [
{ key: 'Accept', value: 'application/json' }
],
authorizationHeader: 'Bearer ' + context.apiToken
}
});
if (apiResult.IsSuccessful) {
var userData = JSON.parse(apiResult.Data);
context.externalUserId = userData.id;
context.userStatus = userData.status;
}
Example 2: POST Request with JSON Body
Send data to an external API:
// Create a customer in external CRM
var customerData = {
firstName: context.customerFirstName,
lastName: context.customerLastName,
email: context.customerEmail,
phoneNumber: context.customerPhone,
accountNumber: context.accountNumber
};
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://crm.example.com/api/customers',
method: 'POST',
headers: [
{ key: 'Content-Type', value: 'application/json' },
{ key: 'X-API-Key', value: 'your-api-key' }
],
body: JSON.stringify(customerData),
contentType: 'application/json'
}
});
if (apiResult.IsSuccessful) {
var response = JSON.parse(apiResult.Data);
context.crmCustomerId = response.customerId;
context.crmSyncDate = new Date().toISOString();
}
Example 3: Payment Gateway Integration
Process payment through external gateway:
// Initiate payment with external gateway
var paymentRequest = {
amount: context.loanAmount,
currency: 'NGN',
customerReference: context.customerReference,
transactionReference: context.transactionId,
callbackUrl: 'https://yourbank.com/api/payment-callback'
};
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://payment-gateway.com/api/v1/charge',
method: 'POST',
headers: [
{ key: 'Content-Type', value: 'application/json' },
{ key: 'X-Business-ID', value: context.businessId }
],
body: JSON.stringify(paymentRequest),
contentType: 'application/json',
authorizationHeader: 'Bearer ' + context.paymentGatewayToken
}
});
if (apiResult.IsSuccessful) {
var paymentResponse = JSON.parse(apiResult.Data);
context.paymentStatus = paymentResponse.status;
context.paymentReference = paymentResponse.reference;
context.authorizationUrl = paymentResponse.authorizationUrl;
} else {
context.paymentError = apiResult.Message;
context.paymentFailed = true;
}
Example 4: KYC Verification Service
Verify customer identity with external KYC service:
// Verify customer BVN with external service
var kycRequest = {
bvn: context.customerBVN,
firstName: context.firstName,
lastName: context.lastName,
dateOfBirth: context.dateOfBirth
};
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://kyc-service.com/api/verify-bvn',
method: 'POST',
headers: [
{ key: 'Content-Type', value: 'application/json' },
{ key: 'X-Verification-Key', value: context.kycApiKey }
],
body: JSON.stringify(kycRequest),
contentType: 'application/json'
}
});
if (apiResult.IsSuccessful) {
var kycResponse = JSON.parse(apiResult.Data);
context.bvnVerified = kycResponse.verified;
context.matchScore = kycResponse.matchScore;
context.verificationDate = new Date().toISOString();
if (kycResponse.verified && kycResponse.matchScore > 90) {
context.kycStatus = 'VERIFIED';
} else {
context.kycStatus = 'REVIEW_REQUIRED';
}
} else {
context.kycStatus = 'VERIFICATION_FAILED';
context.kycError = apiResult.Message;
}
Example 5: PUT Request to Update Record
Update existing record in external system:
// Update loan status in external system
var updateData = {
loanId: context.externalLoanId,
status: 'APPROVED',
approvedAmount: context.approvedLoanAmount,
approvedBy: context.approverName,
approvalDate: new Date().toISOString()
};
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/loans/' + context.externalLoanId,
method: 'PUT',
headers: [
{ key: 'Content-Type', value: 'application/json' }
],
body: JSON.stringify(updateData),
contentType: 'application/json',
authorizationHeader: 'Bearer ' + context.apiToken
}
});
if (!apiResult.IsSuccessful) {
context.syncError = 'Failed to update external system: ' + apiResult.Message;
}
Example 6: Webhook Notification
Send notification to external webhook:
// Notify external system of account opening
var webhookPayload = {
event: 'ACCOUNT_OPENED',
timestamp: new Date().toISOString(),
data: {
accountNumber: context.accountNumber,
customerId: context.customerId,
productType: context.productType,
branchCode: context.branchCode
}
};
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: context.webhookUrl,
method: 'POST',
headers: [
{ key: 'Content-Type', value: 'application/json' },
{ key: 'X-Webhook-Secret', value: context.webhookSecret }
],
body: JSON.stringify(webhookPayload),
contentType: 'application/json'
}
});
// Log webhook result for audit
context.webhookSent = apiResult.IsSuccessful;
context.webhookStatusCode = apiResult.StatusCode;
Advanced Features
Authentication Methods
Bearer Token Authentication
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/endpoint',
method: 'POST',
authorizationHeader: 'Bearer ' + context.accessToken,
body: JSON.stringify(data)
}
});
API Key Authentication
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/endpoint',
method: 'GET',
headers: [
{ key: 'X-API-Key', value: context.apiKey }
]
}
});
Basic Authentication
// Encode credentials
var credentials = context.username + ':' + context.password;
var encodedCredentials = btoa(credentials);
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/endpoint',
method: 'GET',
authorizationHeader: 'Basic ' + encodedCredentials
}
});
Error Handling
Always check the response status and handle errors appropriately:
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/endpoint',
method: 'POST',
body: JSON.stringify(data),
authorizationHeader: 'Bearer ' + context.token
}
});
// Check if request was successful
if (apiResult.IsSuccessful) {
// Parse response
try {
var response = JSON.parse(apiResult.Data);
context.externalId = response.id;
} catch (e) {
context.error = 'Failed to parse API response';
}
} else {
// Handle different error scenarios
if (apiResult.StatusCode === '401') {
context.error = 'Authentication failed - invalid token';
} else if (apiResult.StatusCode === '404') {
context.error = 'Resource not found';
} else if (apiResult.StatusCode === '500') {
context.error = 'External service error';
} else {
context.error = 'API call failed: ' + apiResult.Message;
}
}
Timeout Handling
For long-running API calls, implement timeout logic:
// Make API call
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://slow-api.example.com/endpoint',
method: 'POST',
body: JSON.stringify(data)
}
});
// Check for timeout or network errors
if (!apiResult.IsSuccessful && apiResult.Message.indexOf('timeout') > -1) {
context.apiTimeout = true;
context.retryRequired = true;
}
Response Parsing
Handle different response formats:
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/data',
method: 'GET',
headers: [
{ key: 'Accept', value: 'application/json' }
]
}
});
if (apiResult.IsSuccessful) {
// Parse JSON response
try {
var jsonResponse = JSON.parse(apiResult.Data);
context.parsedData = jsonResponse;
} catch (e) {
// Response might be XML or plain text
context.rawResponse = apiResult.Data;
}
}
Best Practices
1. Store API Credentials Securely
Never hardcode API keys or tokens in your process definitions:
// ❌ BAD: Hardcoded credentials
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/endpoint',
authorizationHeader: 'Bearer hardcoded-token-123' // Don't do this!
}
});
// ✅ GOOD: Use context variables
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: context.apiUrl, // Load from configuration
authorizationHeader: 'Bearer ' + context.apiToken // Load securely
}
});
2. Validate Response Before Parsing
Always validate the response before attempting to parse:
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: { url: 'https://api.example.com/data', method: 'GET' }
});
if (apiResult.IsSuccessful && apiResult.Data) {
try {
var response = JSON.parse(apiResult.Data);
if (response && response.data) {
context.result = response.data;
}
} catch (e) {
context.error = 'Invalid JSON response';
}
}
3. Log API Calls for Audit
Track all external API interactions:
// Log before API call
context.apiCallTimestamp = new Date().toISOString();
context.apiCallUrl = 'https://api.example.com/endpoint';
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: context.apiCallUrl,
method: 'POST',
body: JSON.stringify(data)
}
});
// Log after API call
context.apiResponseCode = apiResult.StatusCode;
context.apiResponseSuccess = apiResult.IsSuccessful;
context.apiResponseTimestamp = new Date().toISOString();
4. Implement Retry Logic
Handle transient failures with retry logic:
var maxRetries = 3;
var retryCount = 0;
var success = false;
while (retryCount < maxRetries && !success) {
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/endpoint',
method: 'POST',
body: JSON.stringify(data)
}
});
if (apiResult.IsSuccessful) {
success = true;
context.apiResponse = apiResult.Data;
} else {
retryCount++;
if (retryCount < maxRetries) {
// Wait before retry (use process timer or delay)
context.retryAttempt = retryCount;
}
}
}
context.apiCallSuccess = success;
context.totalRetries = retryCount;
5. Handle Different Content Types
Specify the correct content type for your requests:
// JSON request
var jsonResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/json',
method: 'POST',
body: JSON.stringify({ key: 'value' }),
contentType: 'application/json'
}
});
// Form data request
var formResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/form',
method: 'POST',
body: 'key1=value1&key2=value2',
contentType: 'application/x-www-form-urlencoded'
}
});
// XML request
var xmlResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/xml',
method: 'POST',
body: '<root><item>value</item></root>',
contentType: 'application/xml'
}
});
HTTP Status Codes
Common status codes you may encounter:
| Status Code | Meaning | Action |
|---|---|---|
| 200 | OK | Success - process response |
| 201 | Created | Resource created successfully |
| 400 | Bad Request | Check request parameters |
| 401 | Unauthorized | Check authentication credentials |
| 403 | Forbidden | Check API permissions |
| 404 | Not Found | Check URL and resource ID |
| 429 | Too Many Requests | Implement rate limiting/retry |
| 500 | Internal Server Error | External service error - may retry |
| 503 | Service Unavailable | Service down - implement retry |
Troubleshooting
Issue 1: "url is required" Error
Problem: Missing or empty URL parameter
Solution:
// Ensure url is provided and not empty
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/endpoint', // Required
method: 'POST'
}
});
Issue 2: Authentication Failures (401)
Problem: Invalid or missing authentication credentials
Solution:
// Check token is valid and not expired
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://api.example.com/endpoint',
authorizationHeader: 'Bearer ' + context.validToken,
headers: [
{ key: 'X-API-Key', value: context.apiKey }
]
}
});
Issue 3: JSON Parsing Errors
Problem: Response is not valid JSON
Solution:
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: { url: 'https://api.example.com/data', method: 'GET' }
});
if (apiResult.IsSuccessful) {
try {
var response = JSON.parse(apiResult.Data);
context.data = response;
} catch (e) {
// Response might not be JSON
context.rawData = apiResult.Data;
context.parseError = e.message;
}
}
Issue 4: Network Timeout
Problem: API call times out
Solution:
// Implement timeout detection and retry
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: {
url: 'https://slow-api.example.com/endpoint',
method: 'GET'
}
});
if (!apiResult.IsSuccessful) {
if (apiResult.Message && apiResult.Message.indexOf('timeout') > -1) {
context.timeoutOccurred = true;
// Implement retry or fallback logic
}
}
Security Considerations
1. HTTPS Only
Always use HTTPS for API calls to ensure data is encrypted:
// ✅ GOOD: Using HTTPS
url: 'https://api.example.com/endpoint'
// ❌ BAD: Using HTTP
url: 'http://api.example.com/endpoint'
2. Validate SSL Certificates
Ensure you're calling legitimate services with valid SSL certificates.
3. Sensitive Data Handling
Never log sensitive data like passwords, tokens, or personal information:
// ❌ BAD: Logging sensitive data
_logger.LogInformation('API Token: ' + context.apiToken);
// ✅ GOOD: Log without sensitive data
_logger.LogInformation('API call completed successfully');
4. Rate Limiting
Implement rate limiting to avoid overwhelming external services:
// Track API call count
if (!context.apiCallCount) {
context.apiCallCount = 0;
}
if (context.apiCallCount < context.maxApiCalls) {
var apiResult = doCmd('ExecuteRestApiCommand', {
Data: { url: 'https://api.example.com/endpoint', method: 'GET' }
});
context.apiCallCount++;
} else {
context.error = 'API call limit reached';
}
Performance Tips
- Minimize API Calls: Cache responses when appropriate
- Use Batch Endpoints: If the external API supports batch operations, use them
- Async Processing: For non-critical integrations, consider async/background processing
- Timeout Configuration: Set appropriate timeouts based on expected response times
- Connection Pooling: The command uses a new HttpClient per request (consider connection pooling for high-volume scenarios)
Related Commands
- SendMailCommand - Send emails
- SendSMSCommand - Send SMS notifications
- RenderHtmlCommand - Render HTML templates
- DocumentRenderV2Command - Generate Word/PDF documents
Summary
ExecuteRestApiCommand is a powerful integration tool that enables your business processes to communicate with external systems. Use it to:
- ✅ Integrate with payment gateways
- ✅ Verify customer data with KYC services
- ✅ Send notifications to webhooks
- ✅ Sync data with external systems
- ✅ Trigger microservices
- ✅ Fetch real-time data from third-party APIs
Remember to handle errors gracefully, implement proper authentication, and log all external interactions for audit purposes.