api.send
api.send(request) is the helper that the scripts of the application wizard use to call the third-party
application themselves. It returns a promise, so use it with await.
const data = await api.send({
verb: 'GET',
baseUrl: appVault.baseUrl,
requestUrl: 'accounts?limit=10',
headers: { Authorization: `Bearer ${appVaultSecret.access_token}` }
});
Not the workflow
api. Workflow and block scripts have their ownapimodule with a differentapi.send(api.send(shortName, request), see built-in helper functions). This page is about the wizard scripts only. There is no application ShortName here: you give the full address inbaseUrl.
Where you can use it​
| Step | Script | api available |
|---|---|---|
| 3. Authentication | Authentication script | Yes |
| 3. Authentication | Callback request script (Callback type) | No |
| 3. Authentication | Post Handler | Yes |
| 4. Context configuration | Script of a question (Context field script) | Yes |
| 5. Re-Authentication | Custom refresh script | Yes |
| 6. Authorization | Authorization script | Yes |
The request​
| Property | Required | Meaning |
|---|---|---|
verb | Yes | HTTP method: GET, POST, PUT, PATCH, DELETE, ... |
baseUrl | Yes | The address of the application's API, for example https://api.example.com. Trailing / are removed. |
requestUrl | Yes | The path and the query string, added to baseUrl, for example oauth/token or accounts?limit=10. Leading / are removed. |
headers | No | Request headers, an object: { 'Content-Type': 'application/json' }. |
data | No | The request body. An object or an array is sent as JSON. A string is sent as it is (use it for form data, XML or plain text) and you must set the Content-Type header yourself. |
responseType | No | How to read the answer: 'json' (default), 'text' or 'arraybuffer'. |
encoding | No | Encoding of the answer, 'utf8' by default. |
getFullResponse | No | true to get the status, the headers and the body instead of the body only (see below). Default false. |
tls | No | Client certificate (mTLS) and TLS settings, see TLS. |
Things to know:
- There is no separate
paramsproperty. Put the query string intorequestUrl. Repeated names are sent as repeated parameters:tag=a&tag=b. Values are decoded and encoded again for you, so write them as you would in a browser address. - There is no
cookiesorbodyContentTypeproperty. Send cookies in theCookieheader and set the body type in theContent-Typeheader. - The request times out after 5 minutes.
- Redirects are followed.
The answer​
By default api.send returns the body of the answer:
- JSON is already converted to an object or an array. If the answer is not valid JSON you get the text as it is;
responseType: 'text'gives a string,'arraybuffer'gives binary data.
With getFullResponse: true you get an object:
| Property | Meaning |
|---|---|
statusCode | The HTTP status, for example 200. |
statusText | The status text, for example OK. |
headers | The headers of the answer (names are in lower case). |
responseUrl | The final address, after redirects. |
content | The body, converted as described above. |
Errors​
- A non-2xx answer does not throw.
api.sendreturns it as it is, so you must check the status yourself. With the defaultgetFullResponse: falseyou get only the body and cannot see that the call failed, therefore in sign-in scripts always usegetFullResponse: trueand checkstatusCode. - An error before or during the call throws an
Error:- the request is wrong:
GET 400 - baseUrl is required in request,... requestUrl and verb are required in request,... Unsupported 'responseType': xml., or a message about wrongtlssettings; - the call itself failed (no connection, certificate rejected, timeout):
GET ECONNREFUSED - <message> Url: <url>.
- the request is wrong:
An error that you do not catch stops the script. What happens next depends on the step, for example a failed
sign-in script leaves the saved appVault and appVaultSecret unchanged.
Test and Preview behave a little differently. The Test tab and the Preview panel of the wizard run the script in your browser and send the call through Canvas. There, a non-2xx answer throws an error (
401 - Unauthorized: <body>) unless you setgetFullResponse: true, and the call is limited to 2 minutes and does not use client certificates. A script withgetFullResponse: trueand its own status check behaves the same in the Preview and on a connected application.
Examples​
Check the status:
const response = await api.send({
verb: 'POST',
baseUrl: appVault.baseUrl,
requestUrl: 'oauth/token',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: new URLSearchParams({
grant_type: 'password',
username: config.username,
password: config.password
}).toString(),
getFullResponse: true
});
if (response.statusCode !== 200 || !response.content) {
throw new Error(`Sign-in failed: ${response.statusCode} ${response.statusText}`);
}
appVaultSecret.access_token = response.content.access_token;
Send JSON:
const items = await api.send({
verb: 'POST',
baseUrl: appVault.baseUrl,
requestUrl: 'search',
headers: { Authorization: `Bearer ${appVaultSecret.access_token}` },
data: { query: 'open', limit: 50 }
});
Read text:
const html = await api.send({
verb: 'GET',
baseUrl: 'https://example.com',
requestUrl: 'status',
responseType: 'text'
});
TLS​
tls is for applications that require a client certificate (mTLS) or a private certificate authority.
| Property | Meaning |
|---|---|
cert, key | The client certificate and its private key, PEM. They must belong together. |
certChain | Intermediate certificates, an array of PEM. |
pfx, passphrase | The client certificate as a base64 P12/PFX bundle (instead of cert + key). |
ca | Own CA certificates (PEM string or an array). They replace the default trusted authorities. |
rejectUnauthorized | Verify the certificate of the server. true by default. |
servername, minVersion, maxVersion, ciphers, honorCipherOrder, sessionTimeout | Advanced TLS settings. minVersion and maxVersion are 'TLSv1', 'TLSv1.1', 'TLSv1.2' or 'TLSv1.3'. |
Certificates are checked before the call (format, validity period, key pair).
Certificates of a connected application are not added to
api.sendautomatically. The certificates that a user uploads on the page of the connected application are used only when Canvas itself sends the request that your Authentication or Re-Authentication script returns (see Authentication). If your sign-in needs mTLS, return the request instead of callingapi.send.
Good practice​
- Always set
getFullResponse: truein sign-in scripts and throw anErrorwhen the status is not what you expect. Canvas does not judge the answer for you. - Never write tokens, passwords or keys into
appVault. UseappVaultSecret. - Keep
baseUrlinappVault(it is not secret) and buildrequestUrlper call.