Skip to main content

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 own api module with a different api.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 in baseUrl.

Where you can use it​

StepScriptapi available
3. AuthenticationAuthentication scriptYes
3. AuthenticationCallback request script (Callback type)No
3. AuthenticationPost HandlerYes
4. Context configurationScript of a question (Context field script)Yes
5. Re-AuthenticationCustom refresh scriptYes
6. AuthorizationAuthorization scriptYes

The request​

PropertyRequiredMeaning
verbYesHTTP method: GET, POST, PUT, PATCH, DELETE, ...
baseUrlYesThe address of the application's API, for example https://api.example.com. Trailing / are removed.
requestUrlYesThe path and the query string, added to baseUrl, for example oauth/token or accounts?limit=10. Leading / are removed.
headersNoRequest headers, an object: { 'Content-Type': 'application/json' }.
dataNoThe 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.
responseTypeNoHow to read the answer: 'json' (default), 'text' or 'arraybuffer'.
encodingNoEncoding of the answer, 'utf8' by default.
getFullResponseNotrue to get the status, the headers and the body instead of the body only (see below). Default false.
tlsNoClient certificate (mTLS) and TLS settings, see TLS.

Things to know:

  • There is no separate params property. Put the query string into requestUrl. 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 cookies or bodyContentType property. Send cookies in the Cookie header and set the body type in the Content-Type header.
  • 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:

PropertyMeaning
statusCodeThe HTTP status, for example 200.
statusTextThe status text, for example OK.
headersThe headers of the answer (names are in lower case).
responseUrlThe final address, after redirects.
contentThe body, converted as described above.

Errors​

  • A non-2xx answer does not throw. api.send returns it as it is, so you must check the status yourself. With the default getFullResponse: false you get only the body and cannot see that the call failed, therefore in sign-in scripts always use getFullResponse: true and check statusCode.
  • 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 wrong tls settings;
    • the call itself failed (no connection, certificate rejected, timeout): GET ECONNREFUSED - <message> Url: <url>.

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 set getFullResponse: true, and the call is limited to 2 minutes and does not use client certificates. A script with getFullResponse: true and 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.

PropertyMeaning
cert, keyThe client certificate and its private key, PEM. They must belong together.
certChainIntermediate certificates, an array of PEM.
pfx, passphraseThe client certificate as a base64 P12/PFX bundle (instead of cert + key).
caOwn CA certificates (PEM string or an array). They replace the default trusted authorities.
rejectUnauthorizedVerify the certificate of the server. true by default.
servername, minVersion, maxVersion, ciphers, honorCipherOrder, sessionTimeoutAdvanced 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.send automatically. 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 calling api.send.

Good practice​

  • Always set getFullResponse: true in sign-in scripts and throw an Error when the status is not what you expect. Canvas does not judge the answer for you.
  • Never write tokens, passwords or keys into appVault. Use appVaultSecret.
  • Keep baseUrl in appVault (it is not secret) and build requestUrl per call.