Balance Exchange
The Balance Exchange API enables merchants to programmatically transfer funds between different currency accounts within their Skrill merchant account. This tool provides the same functionality available through the Skrill Business Portal, allowing you to streamline currency conversions and fund transfers without manual intervention.
Business Benefits
- Automated Currency Management: Eliminate manual currency conversions and transfers
- Real-time Exchange Rates: Access current FX rates with guaranteed validity periods
- Reduced Operational Costs: Minimize manual processing and administrative overhead
- Enhanced Cash Flow Management: Optimize fund allocation across different currency accounts
- Integration Flexibility: Seamlessly integrate with existing business systems and workflows
Prerequisites
Before implementing the Balance Exchange API, ensure you have:
- Enabled Automated Payment Interface: API access must be activated on your account
- API/MQI Password: A secure password specifically configured for API access
- Valid Currency Accounts: At least two currency accounts with sufficient balances
Technical Specifications
API Endpoint
- Base URL:
https://www.skrill.com/app/exchange
- Protocol: HTTPS only
- Authentication: Email and MD5-hashed password
Supported Request Methods
- GET: URL-encoded parameters
- POST (application/x-www-form-urlencoded): Form-encoded data
- POST (multipart/form-data): Multipart form data
Response Formats
- Default: JSON responses
- Alternative: XML responses (specify
Accept: application/xml
header)
Exchange Process Workflow
The Balance Exchange API follows a three-step process designed for security and reliability:
- Preview (Optional): Calculate exchange rates and amounts without executing the transfer
- Prepare: Generate a secure session ID for the exchange transaction
- Exchange: Execute the actual fund transfer using the session ID
API Parameters
Required Parameters
Parameter | Preview | Prepare | Exchange | Description | Example |
---|---|---|---|---|---|
action | ✅ | ✅ | ✅ | Specifies the operation to perform. Must be one of: preview , prepare , or exchange | preview |
email | ✅ | ✅ | ❌ | The email address associated with your Skrill merchant account | merchant@company.com |
password | ✅ | ✅ | ❌ | md5Hex-hashed version of your API/MQI password. | 5d41402abc4b2a76b9719d911017c592 |
fromAccountId | ✅ | ✅ | ❌ | Unique identifier of the source currency account. Use Get Balances API to retrieve account IDs | 5008285931 |
toAccountId | ✅ | ✅ | ❌ | Unique identifier of the destination currency account. Must be different from fromAccountId | 5025309388 |
amount | ✅ | ✅ | ❌ | The amount to exchange. Must be positive with maximum 6 decimal places | 100.50 |
currency | ⚠️ | ⚠️ | ❌ | Currency code for the exchange. Must match either source or destination account currency. Determines which account pays FX fees | EUR |
sid | ❌ | ❌ | ✅ | Session ID returned from the prepare step. Valid for 15 minutes | 2e9c42f8ece2a64f698042328db96468 |
You can get the fromAccountId
and toAccountId
for each currency account along with their available balance using the Get Balances MQI Action
Parameter Details
Currency Parameter Logic
The currency
parameter determines the base currency for the exchange and affects fee allocation:
- If
currency
matchesfromAccountId
currency: FX fees are deducted from the destination account (toAccountId
) - If
currency
matchestoAccountId
currency: FX fees are deducted from the source account (fromAccountId
) - If
currency
is omitted: Defaults to the source account currency (fromAccountId
)
Amount Precision
- Maximum precision: 6 decimal places
- Minimum amount: 0.01 (varies by currency)
- Must be a positive number
Session Management
- Session IDs (
sid
) are valid for 15 minutes after generation - Each session ID can only be used once for exchange execution
API Actions
The Balance Exchange API provides three distinct actions that work together to ensure secure and reliable fund transfers.
Preview Action
The preview action allows you to calculate exchange rates and amounts without executing any actual transfers. This is particularly useful for:
- Rate Discovery: Check current exchange rates before committing to a transfer
- Amount Calculation: Verify the exact amounts that will be transferred
- Cost Analysis: Understand FX fees and total costs before execution
Example Request
The following examples demonstrate how to preview a currency exchange of 1.000 EUR to USD:
- GET Request
- POST (Form Data)
- POST (Multipart)
- JavaScript
curl "https://www.skrill.com/app/exchange?action=preview&email=merchant@company.com&password=5d41402abc4b2a76b9719d911017c592&fromAccountId=5008285930&toAccountId=5025309388&amount=1000¤cy=EUR"
curl -X POST https://www.skrill.com/app/exchange/ \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "action=preview" \
--data "email=merchant@company.com" \
--data "password=5d41402abc4b2a76b9719d911017c592" \
--data "fromAccountId=5008285930" \
--data "toAccountId=5025309388" \
--data "amount=1000" \
--data "currency=EUR"
curl -X POST https://www.skrill.com/app/exchange/ \
-H "Content-Type: multipart/form-data" \
-F "action=preview" \
-F "email=merchant@company.com" \
-F "password=5d41402abc4b2a76b9719d911017c592" \
-F "fromAccountId=5008285930" \
-F "toAccountId=5025309388" \
-F "amount=1000" \
-F "currency=EUR"
const previewExchange = async () => {
const params = new URLSearchParams({
action: 'preview',
email: 'merchant@company.com',
password: '5d41402abc4b2a76b9719d911017c592',
fromAccountId: '5008285930',
toAccountId: '5025309388',
amount: '1000',
currency: 'EUR'
});
const response = await fetch('https://www.skrill.com/app/exchange', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: params
});
const data = await response.json();
console.log('Exchange Preview:', data);
};
Example Response
The preview response provides detailed information about the proposed exchange:
- JSON Response
- XML Response
{
"transaction": {
"fromAccountCurrency": "EUR",
"fromAccountAmount": 1000.000000,
"toAccountCurrency": "USD",
"toAccountAmount": 1085.500000,
"skrillExchangeFxRate": 1.085500,
"fxValidUntil": 1748444198000
}
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<transaction>
<from_account_currency>EUR</from_account_currency>
<from_account_amount>1000.000000</from_account_amount>
<to_account_currency>USD</to_account_currency>
<to_account_amount>1085.500000</to_account_amount>
<skrill_exchange_fx_rate>1.085500</skrill_exchange_fx_rate>
<fx_valid_until>1748444198000</fx_valid_until>
</transaction>
</response>
Response Field Descriptions
Field | Description | Example |
---|---|---|
fromAccountCurrency | Currency code of the source account | EUR |
fromAccountAmount | Amount to be deducted from source account | 1000.000000 |
toAccountCurrency | Currency code of the destination account | USD |
toAccountAmount | Amount to be credited to destination account | 1085.500000 |
skrillExchangeFxRate | Exchange rate applied for the conversion | 1.085500 |
fxValidUntil | Unix timestamp indicating rate validity expiration | 1748444198000 |
Rate Validity Guarantee
The fxValidUntil field (fx_valid_until in XML) is a Unix timestamp indicating the validity window of the exchange rate. Skrill guarantees that the FX rate provided in the preview response will be applied during the exchange step only if the following conditions are met:
- The
fromAccountId
,toAccountId
, andcurrency
parameters remain unchanged between preview and prepare steps - The exchange step is executed before the fxValidUntil timestamp expires
- The exchange amount remains the same
The current validity period is 5 minutes. If the prepare step is performed after fxValidUntil, the FX rate may differ from the one shown in the preview step, as the current market rate at that time will be used instead.
Prepare Action
The prepare action generates a secure session ID that must be used in the subsequent exchange step. This two-step process ensures transaction security and prevents unauthorized exchanges.
Key Features:
- Session Generation: Creates a unique, time-limited session ID
- Parameter Validation: Validates all exchange parameters before execution
- Security Layer: Adds an additional security checkpoint before fund transfer
- Rate Locking: Locks in the exchange rate (if preview was used within validity period)
- Session IDs expire after 15 minutes
- Each session ID can only be used once
Example Request
Prepare the exchange with the same parameters used in the preview:
- GET Request
- POST (Form Data)
- POST (Multipart)
- JavaScript
curl "https://www.skrill.com/app/exchange?action=prepare&email=merchant@company.com&password=5d41402abc4b2a76b9719d911017c592&fromAccountId=5008285930&toAccountId=5025309388&amount=1000¤cy=EUR"
curl -X POST https://www.skrill.com/app/exchange/ \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "action=prepare" \
--data "email=merchant@company.com" \
--data "password=5d41402abc4b2a76b9719d911017c592" \
--data "fromAccountId=5008285930" \
--data "toAccountId=5025309388" \
--data "amount=1000" \
--data "currency=EUR"
curl -X POST https://www.skrill.com/app/exchange/ \
-H "Content-Type: multipart/form-data" \
-F "action=prepare" \
-F "email=merchant@company.com" \
-F "password=5d41402abc4b2a76b9719d911017c592" \
-F "fromAccountId=5008285930" \
-F "toAccountId=5025309388" \
-F "amount=1000" \
-F "currency=EUR"
const prepareExchange = async () => {
const params = new URLSearchParams({
action: 'prepare',
email: 'merchant@company.com',
password: '5d41402abc4b2a76b9719d911017c592',
fromAccountId: '5008285930',
toAccountId: '5025309388',
amount: '1000',
currency: 'EUR'
});
const response = await fetch('https://www.skrill.com/app/exchange', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: params
});
const data = await response.json();
console.log('Session ID:', data.sid);
};
Example Response
- JSON
- XML
{
"sid": "1e8ff8f16ec19b7f337e03cde2f1692f"
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<sid>1e8ff8f16ec19b7f337e03cde2f1692f</sid>
</response>
Exchange Action
The exchange action executes the actual fund transfer between accounts using the session ID obtained from the prepare step. This is the final step that completes the currency exchange process.
Important Considerations:
- One-time Use: Each session ID can only be used once
- Irreversible: Once an exchange has been executed, it cannot be reversed. A new exchange must be initiated if changes are required.
- Immediate Processing: Funds are transferred immediately upon successful execution
Example Request
Execute the exchange using the session ID from the prepare step:
- GET Request
- POST (Form Data)
- POST (Multipart)
- JavaScript
curl "https://www.skrill.com/app/exchange?action=exchange&sid=1e8ff8f16ec19b7f337e03cde2f1692f"
curl -X POST https://www.skrill.com/app/exchange/ \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "action=exchange" \
--data "sid=1e8ff8f16ec19b7f337e03cde2f1692f"
curl -X POST https://www.skrill.com/app/exchange/ \
-H "Content-Type: multipart/form-data" \
-F "action=exchange" \
-F "sid=1e8ff8f16ec19b7f337e03cde2f1692f"
const executeExchange = async (sessionId) => {
const params = new URLSearchParams({
action: 'exchange',
sid: sessionId
});
const response = await fetch('https://www.skrill.com/app/exchange', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: params
});
const data = await response.json();
if (data.transaction && data.transaction.status === 2) {
console.log('Exchange successful:', data.transaction);
console.log('Transaction ID:', data.transaction.mbTransactionId);
} else {
console.error('Exchange failed:', data);
}
};
Example Response
The exchange response confirms the successful completion of the fund transfer:
- JSON Response
- XML Response
{
"transaction": {
"status": 2,
"statusMsg": "processed",
"mbTransactionId": 5098434837,
"fromAccountCurrency": "EUR",
"fromAccountAmount": 1000.000000,
"toAccountCurrency": "USD",
"toAccountAmount": 1085.500000,
"skrillExchangeFxRate": 1.085500
}
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<transaction>
<status>2</status>
<status_msg>processed</status_msg>
<mb_transaction_id>5098434837</mb_transaction_id>
<from_account_currency>EUR</from_account_currency>
<from_account_amount>1000.000000</from_account_amount>
<to_account_currency>USD</to_account_currency>
<to_account_amount>1085.500000</to_account_amount>
<skrill_exchange_fx_rate>1.085500</skrill_exchange_fx_rate>
</transaction>
</response>
Response Field Descriptions
Field | Description | Example |
---|---|---|
status | Transaction status code | 2 |
statusMsg | Human-readable status message | processed |
mbTransactionId | Skrill's internal transaction id | 5098434837 |
fromAccountCurrency | Currency code of the source account | EUR |
fromAccountAmount | Amount deducted from source account | 1000.000000 |
toAccountCurrency | Currency code of the destination account | USD |
toAccountAmount | Amount credited to destination account | 1085.500000 |
skrillExchangeFxRate | Exchange rate applied for the conversion | 1.085500 |
Error Categories
Authentication Errors
Error Code | Description | Affects Actions | Resolution |
---|---|---|---|
INVALID_LOGIN | Missing username or password parameters | preview, prepare | Include both email and password parameters |
INVALID_EMAIL | Invalid email format | preview, prepare | Verify email format and ensure it matches your merchant account |
INVALID_PASSWORD | Password exceeds maximum length | preview, prepare | Ensure password is MD5-hashed and within length limits |
CANNOT_LOGIN | Incorrect email or password | preview, prepare | Verify credentials and ensure API access is enabled |
Parameter Validation Errors
Error Code | Description | Affects Actions | Resolution |
---|---|---|---|
INVALID_OR_MISSING_ACTION | Invalid or missing action parameter | All actions | Use one of: preview , prepare , exchange |
MISSING_AMOUNT | Amount parameter is missing | preview, prepare | Include the amount parameter |
INVALID_AMOUNT | Invalid amount (zero, negative, or excessive precision) | preview, prepare | Use positive amounts with max 6 decimal places |
MISSING_FROM_ACCOUNT_ID | Source account ID is missing | preview, prepare | Include valid fromAccountId parameter |
INVALID_FROM_ACCOUNT_ID | Invalid source account ID format | preview, prepare | Use numeric account ID from Get Balances API |
MISSING_TO_ACCOUNT_ID | Destination account ID is missing | preview, prepare | Include valid toAccountId parameter |
INVALID_TO_ACCOUNT_ID | Invalid destination account ID format | preview, prepare | Use numeric account ID from Get Balances API |
INVALID_CURRENCY | Invalid currency code | preview, prepare | Use valid ISO currency codes |
FROM_ACCOUNT_ID_MUST_BE_DIFFERENT_THAN_TO_ACCOUNT_ID | Source and destination accounts are the same | preview, prepare | Use different account IDs for source and destination |
Business Logic Errors
Error Code | Description | Affects Actions | Resolution |
---|---|---|---|
ACCOUNT_ID_DOES_NOT_BELONG_TO_CUSTOMER | Account doesn't belong to merchant | preview, prepare | Verify account IDs belong to your merchant account |
CURRENCY_MUST_BE_THE_SAME_AS_ACCOUNT_CURRENCY | Currency doesn't match account currencies | preview, prepare | Use currency that matches either source or destination account |
NOT_ENOUGH_BALANCE | Insufficient funds in source account | All actions | Check account balance and reduce amount |
Session Management Errors
Error Code | Description | Affects Actions | Resolution |
---|---|---|---|
SESSION_EXPIRED | Session ID has expired (15 minutes) | exchange | Generate new session ID using prepare action |
EXECUTION_PENDING | Exchange is still processing | exchange | Wait for completion or check status |
System Errors
Error Code | Description | Affects Actions |
---|---|---|
GENERIC_ERROR | Unexpected system error | All actions |
Error Response Examples
JSON Error Response
{
"error": {
"message": "INVALID_CURRENCY"
}
}
XML Error Response
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<error>
<error_msg>INVALID_CURRENCY</error_msg>
</error>
</response>