Skip to main content

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

ParameterTypeRequiredDescription
urlstringYesThe full URL of the API endpoint to call
methodstringNoHTTP method: GET, POST, PUT, PATCH, DELETE (default: POST)
headersarrayNoArray of header objects with key and value properties
bodystringNoRequest body as a string (ignored for GET requests)
contentTypestringNoContent-Type for the request body (default: application/json)
authorizationHeaderstringNoAuthorization 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 CodeMeaningAction
200OKSuccess - process response
201CreatedResource created successfully
400Bad RequestCheck request parameters
401UnauthorizedCheck authentication credentials
403ForbiddenCheck API permissions
404Not FoundCheck URL and resource ID
429Too Many RequestsImplement rate limiting/retry
500Internal Server ErrorExternal service error - may retry
503Service UnavailableService 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

  1. Minimize API Calls: Cache responses when appropriate
  2. Use Batch Endpoints: If the external API supports batch operations, use them
  3. Async Processing: For non-critical integrations, consider async/background processing
  4. Timeout Configuration: Set appropriate timeouts based on expected response times
  5. Connection Pooling: The command uses a new HttpClient per request (consider connection pooling for high-volume scenarios)

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.