- When to use axios and when to use curl
- Entry point — axios.getAxios()
- HTTP methods
- Response and error handling
- Raw variants — access to status and headers
- XML or plain text — Buffer.from
- Sending files and FormData
- Authentication: Vault and certificates
- Usage examples
- Difference between curl and axios — comparison
AXIOS API
- When to use axios and when to use curl
- Entry point — axios.getAxios()
- HTTP methods
- Response and error handling
- Raw variants — access to status and headers
- XML or plain text — Buffer.from
- Sending files and FormData
- Authentication: Vault and certificates
- Usage examples
- Difference between curl and axios — comparison
For calling third-party APIs, the system supports the curl library and — new since TAS 5.7 — the axios library. This article summarizes how to use axios in TAS, when to prefer it over curl, and how to handle responses including errors.
When to use axios and when to use curl
For new HTTP/HTTPS calls, axios is the recommended choice. Compared to curl it offers the following advantages:
- Clearer, shorter syntax — instead of several
setOptcalls, a singleaxios.getAxios().get(url)is enough. For common operations (GET, POST, PATCH…) there is no need to manually set the request type, headers, or body formatting. - Better response handling —
axiosautomatically parses the JSON response according toContent-Type. Classic methods return the parsed data directly (see the Response handling section). - Easier maintenance and readability — the structure matches common modern JavaScript syntax, so consultants and developers understand what the code does more quickly.
axios works only for HTTP/HTTPS requests. For other protocols — SMTP (sending e-mails), FTP, IMAP/POP3 — you must continue to use the curl library.Entry point — axios.getAxios()
Every call starts with the axios.getAxios(config?) function, which returns a client. The individual HTTP methods are then called on the client. The optional config lets you set baseURL, timeout, and headers shared across all calls made by that client.
const client = axios.getAxios({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: { 'Accept': 'application/json' }
});
const items = client.get('/items');axios calls are synchronous — they return the result directly. Do not use async, await, Promise, or .then() — it collides with TAS transpilation and the calculation will fail silently.HTTP methods
axios supports all common HTTP methods.
GET — retrieve data from an API (e.g. a list of items).
axios.getAxios().get('https://api.example.com/items');POST — send data to the server (e.g. create a new item).
axios.getAxios().post('https://api.example.com/items', {
name: 'New item'
});PUT — full update of an existing item.
axios.getAxios().put('https://api.example.com/items/123', {
name: 'Updated item'
});PATCH — partial update of an item (e.g. a single field).
axios.getAxios().patch('https://api.example.com/items/123', {
status: 'active'
});DELETE — delete an item.
axios.getAxios().delete('https://api.example.com/items/123');request — generic call, when you need to set the method dynamically or assemble the configuration.
axios.getAxios().request({
method: 'patch',
url: 'https://api.example.com/items/123',
data: { status: 'done' }
});Response and error handling
get/post/put/patch/delete, request) return the parsed data directly — not a wrapper with a .data property. That is, const items = client.get('/items'); and items is already the array of items. This is the most common source of errors when migrating from other libraries — do not reach for response.data with classic methods.Error behavior:
- A non-2xx status throws an error. The error carries an
err.metaproperty with the object{ status, statusText, data }. Always guard in thecatchblock — the error may not be HTTP (timeout, DNS), in which caseerr.metadoes not exist:
try {
const data = axios.getAxios().get('https://api.example.com/items');
proc.warn('[API][OK]', { data });
} catch (err) {
const meta = (err && err.meta) || {};
proc.warn(`[API][Error] ${meta.statusText || err.message}`, { cause: err });
}0, in which case timeout calculations apply (default 120 s). For external APIs, always set an explicit timeout in the config.Raw variants — access to status and headers
The raw variants (requestRaw, sendFileRaw, sendFilesRaw) return the full response object { data, status, statusText, headers }. Use them only occasionally — when you need the status or headers from a successful response (e.g. a batch ID from a header). Unlike classic methods, they do not throw on non-2xx, so you must check the status manually.
Usage example
const config = {
method: 'get',
url: 'https://api.example.com/items/123'
};
const result = axios.getAxios().requestRaw(config);
if (result.status !== 200) {
throw new Error(`[API][Error] ${result.statusText}`);
}Typical response
{
"data": {
// Content returned by the server (e.g. JSON data)
},
"status": 200,
"statusText": "OK",
"headers": {
"content-type": "application/json",
"date": "Mon, 22 Jul 2025 09:44:24 GMT"
}
}XML or plain text — Buffer.from
axios passes data natively as JSON. If you need to send XML, plain text, etc., you must tell axios not to transform the data — this is what Buffer.from is for. The function converts a text string into binary data (Buffer) in UTF-8 encoding.
const xml = '<soap>...</soap>';
const payload = Buffer.from(xml, 'utf-8');
axios.getAxios().post('https://api.example.com/soap', payload, {
headers: { 'Content-Type': 'text/xml' }
});
'Content-Type': 'application/x-www-form-urlencoded' and always encode the values with encodeURIComponent — a password containing a special character will otherwise break the request.Sending files and FormData
A single file — sendFile (raw variant sendFileRaw since v5.7.37):
const file = lib.getFileContents('/path/to/file.txt');
axios.getAxios().sendFile('https://api.example.com/upload', file, {
headers: { 'Content-Type': 'application/octet-stream' }
});Multiple files via FormData — sendFiles (raw variant sendFilesRaw since v5.7.37):
const FormData = require('form-data');
const form = new FormData();
form.append('file1', lib.getFileContents('/path/to/file1.jpg'));
form.append('file2', lib.getFileContents('/path/to/file2.jpg'));
axios.getAxios().sendFiles('https://api.example.com/upload', form, {
headers: form.getHeaders()
});Form data — post with FormData:
const FormData = require('form-data');
const form = new FormData();
form.append('name', 'Test');
form.append('email', 'test@example.com');
axios.getAxios().post('https://api.example.com/form', form, {
headers: form.getHeaders()
});Example — sending a file to a system with an API key in the header
const URL = 'https://api.example.com/123';
const ocpKey = 'xxxxx';
const documentName = vars['attachedInvPDF'].getValue();
const invNumber = vars['internalNumber'].getValue() + path.extname(documentName[0]);
const dmsEntity = storage.getDmsEntity(documentName);
const filePath = exportDmsFile(dmsEntity, invNumber);
const result = axios.getAxios({
headers: { 'Ocp-Apim-Subscription-Key': ocpKey }
}).sendFileRaw(URL, filePath);
Sample response
Expand sample response (sendFileRaw)
{
"data": "",
"status": 202,
"statusText": "Accepted",
"headers": {
"content-length": "0",
"operation-location": "https://api.example.com/123",
"apim-request-id": "xxx-abfd-xx-a820-xxxx",
"x-ms-region": "West Europe",
"date": "Thu, 24 Jul 2025 09:43:36 GMT"
}
}Authentication: Vault and certificates
Secrets (API keys, tokens, passwords) and certificates are never written directly into the code — they would leak in the template export as well as in the log. TAS has dedicated mechanisms for them, described in separate articles:
- Authentication via the Vault — injecting tokens, API keys, and passwords into headers, query parameters, and the request body without the secret passing through the code:
- Client SSL certificates (mTLS) — configuring certificates for mutually authenticated HTTPS connections:
Usage examples
GET — retrieving exchange rates from the CNB
function axiosGetDataByURL(requestURL) {
try {
return axios.getAxios().get(requestURL);
} catch (error) {
return {
error: true,
fullError: error,
statusCode: error?.meta?.status,
statusText: error?.meta?.statusText
};
}
}
try {
const cnbExchangeRatesURL = `https://www.cnb.cz/en/financial-markets/foreign-exchange-market/central-bank-exchange-rate-fixing/central-bank-exchange-rate-fixing/daily.xml`;
const requestResponse = axiosGetDataByURL(cnbExchangeRatesURL);
if (requestResponse?.error) {
throw new Error(`[CNB][Response][Error] ${requestResponse?.statusText}`, {
cause: requestResponse?.fullError
});
}
proc.warn(`[CNB][ResponseData]`, { requestResponse });
} catch (error) {
proc.warn(
`An error occurred while downloading data from the CNB: ${error?.message || `Unknown error`} (expand the log for more details)`,
{ cause: error?.cause }
);
}PATCH — updating data on docs.syca.app
function patchMainBody(articleId, newBody) {
const url = `https://api.helpdocs.io/v1/article/${articleId}`;
const payload = { body: newBody };
const requester = axios.getAxios({
timeout: 10000,
headers: { 'Authorization': 'Bearer xxxxxxxx' }
});
return requester.patch(url, payload);
}Bearer xxxxxxxx with a token from the Vault — see the link above.Difference between curl and axios — comparison
Calling CNB exchange rates — curl
function rateCNB(exchangeRateDate, currency, reportingCurrency) {
let formatDate = lib.format(exchangeRateDate, "d.m.Y");
curl.start();
curl.setOpt('CUSTOMREQUEST', 'GET');
curl.setOpt('FOLLOWLOCATION', true);
curl.setOpt('FAILONERROR', false);
curl.setOpt('SSL_VERIFYPEER', false);
curl.setOpt('SSL_VERIFYHOST', false);
curl.setOpt('TIMEOUT', 30);
curl.setOpt('HTTPHEADER', [
'Content-Type: application/json',
'Accept: application/json'
]);
curl.setOpt('URL', `https://www.cnb.cz/.../daily.txt?date=${formatDate}`);
var crossRate = curl.perform();
try {
const body = crossRate.data;
// ...
}
}Calling CNB exchange rates — axios
function rateCNB(exchangeRateDate, currency, reportingCurrency) {
let formatDate = lib.format(exchangeRateDate, "d.m.Y");
const url = `https://www.cnb.cz/.../daily.txt?date=${formatDate}`;
const body = axios.getAxios().get(url);
try {
const rows = body.split('\n');
// ...
}
}setOpt configuration in curl collapse to a single get(url) with axios — and the response is right there in body, without reaching for .data.
Updated
by Frantisek Brych