Code Backed Integrations [Script Editor]
Last updated: April 16, 2026
Getting Started
Code Mode scripts are small JavaScript functions that run when YeshID needs to create, update, import, or remove access in another app. A script reads action data from context, calls the target app's API, and returns true when the action succeeds.
Use Test to run the current script with sample action data. The summary shows whether the run passed, how long it took, and when it started. Test mode validates YeshID helper calls without applying those helper-side changes, but direct fetch() calls still send real API requests, so use safe test credentials or test endpoints.
The tabs beside the editor help you debug each run:
Console shows
console.log,console.warn, andconsole.erroroutput. When a log includes a line number, select it to jump back to that line in the script.Network shows each
fetch()request, including method, URL, status, duration, headers, request body, and response body.Actions shows YeshID helper calls such as
importUsers()andimportGroups(), with their validated input and outcome.Library lists available helper actions and their expected inputs and outputs.
Versions shows published and draft versions, and lets you revert to an earlier version.
Properties stores reusable script settings. Read them in code with
context.get('properties').
Use Publish after a successful test to make the script active. Use the Rae chat window below the editor to ask for code changes; review the proposed diff before accepting it.
Most scripts follow this basic shape:
function run(context) {var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};var user = account.user || {};
var response = fetch((auth.baseUrl || '') + '/users', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + (auth.token || ''),
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: user.email || '',
username: account.accountName || user.email || ''
})});
return response && response.ok;}Use the examples below as starting points for common actions such as Create User, Import Groups, and Add To Role. Adjust the endpoint, payload, and response handling for the app you are connecting.
Built-in Functions
These functions are available inside run(context).
context.get(key)
Reads data YeshID passes into the script. Common keys are auth, input, and properties.
var auth = context.get('auth') || {};var input = context.get('input') || {};var properties = context.get('properties') || {};
var baseUrl = auth.baseUrl || '';var token = auth.token || '';var department = properties.department || '';auth object
context.get('auth') contains the connection settings from the Integration setup. It always uses the same script-facing key names, even when the setup screen labels are different.
Do not log the full auth object. It can contain tokens, API keys, usernames, and passwords.
auth.baseUrlis the API base URL configured for the integration.Bearer auth provides
auth.token.OAuth2 auth provides
auth.token, and may also provideauth.tokenType,auth.headerKey, andauth.headerValuePrefix.API key auth provides
auth.apiKey,auth.apiKeyName, andauth.apiKeyLocation.auth.apiKeyLocationisHEADERorQUERY.Basic auth provides
auth.usernameandauth.password.
Bearer token:
var auth = context.get('auth') || {};var headers = {'Authorization': 'Bearer ' + (auth.token || ''),'Accept': 'application/json'};OAuth2 token with custom header settings:
var auth = context.get('auth') || {};var headers = {};var headerKey = auth.headerKey || 'Authorization';var headerValuePrefix = auth.headerValuePrefix || 'Bearer';
headers[headerKey] = headerValuePrefix + ' ' + (auth.token || '');API key in a header:
var auth = context.get('auth') || {};var headers = {};
if (auth.apiKeyLocation === 'HEADER') {headers[auth.apiKeyName || 'X-API-Key'] = auth.apiKey || '';}API key in a query string:
var auth = context.get('auth') || {};var url = (auth.baseUrl || '') + '/users';var separator = url.indexOf('?') === -1 ? '?' : '&';
if (auth.apiKeyLocation === 'QUERY') {url += separator + encodeURIComponent(auth.apiKeyName || 'api_key') + '=' + encodeURIComponent(auth.apiKey || '');}Basic auth:
var auth = context.get('auth') || {};var credentials = (auth.username || '') + ':' + (auth.password || '');var headers = {'Authorization': 'Basic ' + btoa(credentials)};input object
context.get('input') contains the action data for the current run. Import actions usually do not receive an input object because the script is expected to fetch records from the app and call helper functions such as importUsers(), importGroups(), or importEmployees().
Actions that operate on a user account receive input.account:
var input = context.get('input') || {};var account = input.account || {};var user = account.user || {};var manager = user.manager || {};
var accountName = account.accountName || '';var externalId = account.externalId || '';var email = user.email || '';var fullName = user.fullName || '';var managerEmail = manager.email || '';var customValue = (user.customFields || {}).employeeId || '';input.account can include:
accountNameexternalIdextendedInforoles, withid,name,externalId, anduserRequestableuser.firstName,user.lastName,user.fullName,user.email,user.status,user.title,user.address,user.startDate,user.endDateuser.customFields, keyed by custom field nameuser.rolesuser.groups, withid,name, andtypeuser.manager, when loaded, withfirstName,lastName,fullName,email,status,title,address,startDate,endDate,customFields,roles, andgroups
Group membership actions receive both input.account and input.group:
var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};var group = input.group || {};
var url = (auth.baseUrl || '') + '/groups/' + group.externalId + '/members/' + account.externalId;input.group can include externalId, name, and members. Each member has groupExternalId, memberExternalId, and memberType.
Role membership actions receive both input.account and input.role:
var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};var role = input.role || {};
var url = (auth.baseUrl || '') + '/roles/' + role.externalId + '/members/' + account.externalId;input.role can include id, name, externalId, and userRequestable.
fetch(url, options)
Sends a synchronous HTTP request. The response includes status, ok, text(), json(), and headers.
var response = fetch('https://api.example.com/users', {method: 'GET',headers: {
'Authorization': 'Bearer ' + token,
'Accept': 'application/json'}});
if (!response || !response.ok) {console.error('Request failed', response ? response.status : 'no response');return false;}
var users = response.json().users || [];var requestId = response.headers.get('x-request-id') || '';console.log(), console.warn(), console.error()
Writes messages to the Console tab. Use errors for failures that should be easy to spot during testing.
console.log('Starting import');console.warn('Skipping user without email');console.error('Import failed', 500);btoa(str)
Encodes a string as Base64. This is usually used for Basic Auth headers.
var credentials = (auth.username || '') + ':' + (auth.password || '');var response = fetch((auth.baseUrl || '') + '/users', {method: 'GET',headers: {
'Authorization': 'Basic ' + btoa(credentials)}});importUsers(users)
Validates or imports application accounts. Each user must include externalId, email, and displayName.
importUsers([{
externalId: 'user-123',
email: 'user@example.com',
displayName: 'Example User',
firstName: 'Example',
lastName: 'User',
active: true}]);importGroups(groups)
Validates or imports application groups and optional group members. Each group must include externalId and name.
importGroups([{
externalId: 'group-123',
name: 'Engineering',
members: [
{
memberExternalId: 'user-123',
memberType: 'USER'
}
]}]);importEmployees(employees)
Validates or imports employee records for onboard/offboard workflows. Each employee must include externalId.
Use top-level managerEmail or managerExternalId to resolve the employee's manager. Set only one manager field on each employee.
importEmployees([{
externalId: 'employee-123',
email: 'employee@example.com',
firstName: 'Example',
lastName: 'Employee',
startDate: '2026-05-01',
endDate: '',
managerEmail: 'manager@example.com',
customFields: {
department: 'IT'
}}]);Import Users
Helper used inside the script:
importUsers([...])Input: no per-user
inputpayload; the script usually fetches from the upstream app and emits users into YeshID.
function run(context) {var auth = context.get('auth') || {};var baseUrl = auth.baseUrl || '';var token = auth.token || '';var response = fetch(baseUrl + '/users', {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + token,
'Accept': 'application/json'
}});
if (!response || !response.ok) {
console.error('Import users failed', response ? response.status : 'no response');
return false;}
var payload = response.json() || {};var rows = payload.users || [];var users = [];var i;var row;
for (i = 0; i < rows.length; i++) {
row = rows[i] || {};
users.push({
externalId: row.id,
email: row.email,
displayName: row.fullName || ((row.firstName || '') + ' ' + (row.lastName || '')),
firstName: row.firstName || '',
lastName: row.lastName || '',
active: row.active !== false
});}
importUsers(users);return true;}Create User
Input:
input.account
For account actions, context.get('input') includes the account and mapped user:
{account: {
accountName: "Example User",
externalId: "example-123",
roles: [
{
id: "...",
externalId: "example-role-123",
name: "Member"
}
],
user: {
firstName: "Example",
lastName: "User",
fullName: "Example User",
email: "user@example.com",
customFields: {
department: "IT"
},
manager: {
fullName: "Example Manager",
email: "manager@example.com"
}
}}}When manager data is available, it is nested at input.account.user.manager.
function run(context) {var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};var user = account.user || {};var manager = user.manager || {};var response = fetch((auth.baseUrl || '') + '/users', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + (auth.token || ''),
'Content-Type': 'application/json'
},
body: JSON.stringify({
externalId: account.externalId || '',
username: account.accountName || user.email || '',
email: user.email || '',
firstName: user.firstName || '',
lastName: user.lastName || '',
managerEmail: manager.email || ''
})});
if (!response || !response.ok) {
console.error('Create user failed', response ? response.status : 'no response');
return false;}
console.log('Created user', user.email || account.accountName || account.externalId || '');return true;}Update User
Input:
input.account; uses the account-shaped input from Create User.
function run(context) {var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};var user = account.user || {};var externalId = account.externalId || '';
if (!externalId) {
console.error('Update user requires input.account.externalId');
return false;}
var response = fetch((auth.baseUrl || '') + '/users/' + externalId, {
method: 'PATCH',
headers: {
'Authorization': 'Bearer ' + (auth.token || ''),
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: account.accountName || '',
email: user.email || '',
firstName: user.firstName || '',
lastName: user.lastName || '',
department: (user.customFields || {}).department || ''
})});
if (!response || !response.ok) {
console.error('Update user failed', response ? response.status : 'no response');
return false;}
return true;}Delete User
Input:
input.account; requiresinput.account.externalId.
function run(context) {var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};var externalId = account.externalId || '';
if (!externalId) {
console.error('Delete user requires input.account.externalId');
return false;}
var response = fetch((auth.baseUrl || '') + '/users/' + externalId, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer ' + (auth.token || '')
}});
if (!response || !response.ok) {
console.error('Delete user failed', response ? response.status : 'no response');
return false;}
return true;}Deactivate User
Input:
input.account; requiresinput.account.externalId.
function run(context) {var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};var externalId = account.externalId || '';
if (!externalId) {
console.error('Deactivate user requires input.account.externalId');
return false;}
var response = fetch((auth.baseUrl || '') + '/users/' + externalId, {
method: 'PATCH',
headers: {
'Authorization': 'Bearer ' + (auth.token || ''),
'Content-Type': 'application/json'
},
body: JSON.stringify({
active: false
})});
if (!response || !response.ok) {
console.error('Deactivate user failed', response ? response.status : 'no response');
return false;}
return true;}Import Groups
Alias:
importGroupsHelper used inside the script:
importGroups([...])Input: no per-group
inputpayload; the script usually fetches groups from the upstream app and emits them into YeshID.
function run(context) {var auth = context.get('auth') || {};var response = fetch((auth.baseUrl || '') + '/groups?includeMembers=true', {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + (auth.token || ''),
'Accept': 'application/json'
}});
if (!response || !response.ok) {
console.error('Import groups failed', response ? response.status : 'no response');
return false;}
var payload = response.json() || {};var rows = payload.groups || [];var groups = [];var i;var j;var row;var memberRows;var members;
for (i = 0; i < rows.length; i++) {
row = rows[i] || {};
memberRows = row.members || [];
members = [];
for (j = 0; j < memberRows.length; j++) {
members.push({
memberExternalId: memberRows[j].id,
memberType: 'USER'
});
}
groups.push({
externalId: row.id,
name: row.name,
members: members
});}
importGroups(groups);return true;}Add To Group
Alias:
addToGroupInput:
input.accountandinput.group
For group membership actions, context.get('input') includes both the account and target group:
{account: {
externalId: "example-user-123",
user: {
email: "user@example.com"
}},group: {
externalId: "example-group-123",
name: "Example Group",
members: [
{
memberExternalId: "example-user-123",
memberType: "USER"
}
]}}function run(context) {var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};var group = input.group || {};
if (!account.externalId || !group.externalId) {
console.error('Add to group requires account.externalId and group.externalId');
return false;}
var response = fetch((auth.baseUrl || '') + '/groups/' + group.externalId + '/members', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + (auth.token || ''),
'Content-Type': 'application/json'
},
body: JSON.stringify({
memberExternalId: account.externalId,
memberType: 'USER'
})});
if (!response || !response.ok) {
console.error('Add to group failed', response ? response.status : 'no response');
return false;}
return true;}Remove From Group
Input:
input.accountandinput.group; uses the same group membership input as Add To Group.
function run(context) {var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};var group = input.group || {};
if (!account.externalId || !group.externalId) {
console.error('Remove from group requires account.externalId and group.externalId');
return false;}
var response = fetch((auth.baseUrl || '') + '/groups/' + group.externalId + '/members/' + account.externalId, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer ' + (auth.token || '')
}});
if (!response || !response.ok) {
console.error('Remove from group failed', response ? response.status : 'no response');
return false;}
return true;}Add To Role
Input:
input.accountandinput.role
For role membership actions, context.get('input') includes both the account and target role:
{account: {
externalId: "example-user-123",
user: {
email: "user@example.com"
}},role: {
externalId: "example-role-123",
name: "Example Role"}}function run(context) {var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};var role = input.role || {};
if (!account.externalId || !role.externalId) {
console.error('Add to role requires account.externalId and role.externalId');
return false;}
var response = fetch((auth.baseUrl || '') + '/roles/' + role.externalId + '/members', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + (auth.token || ''),
'Content-Type': 'application/json'
},
body: JSON.stringify({
memberExternalId: account.externalId
})});
if (!response || !response.ok) {
console.error('Add to role failed', response ? response.status : 'no response');
return false;}
return true;}Remove From Role
Input:
input.accountandinput.role; uses the same role membership input as Add To Role.
function run(context) {var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};var role = input.role || {};
if (!account.externalId || !role.externalId) {
console.error('Remove from role requires account.externalId and role.externalId');
return false;}
var response = fetch((auth.baseUrl || '') + '/roles/' + role.externalId + '/members/' + account.externalId, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer ' + (auth.token || '')
}});
if (!response || !response.ok) {
console.error('Remove from role failed', response ? response.status : 'no response');
return false;}
return true;}Import Employees
Helper used inside the script:
importEmployees([...])Input: no per-employee
inputpayload; the script usually fetches employee records and emits them into YeshID.
function run(context) {var auth = context.get('auth') || {};var response = fetch((auth.baseUrl || '') + '/employees', {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + (auth.token || ''),
'Accept': 'application/json'
}});
if (!response || !response.ok) {
console.error('Import employees failed', response ? response.status : 'no response');
return false;}
var payload = response.json() || {};var rows = payload.employees || [];var employees = [];var i;var row;
for (i = 0; i < rows.length; i++) {
row = rows[i] || {};
employees.push({
externalId: row.id,
email: row.email || '',
firstName: row.firstName || '',
lastName: row.lastName || '',
startDate: row.startDate || '',
endDate: row.endDate || '',
managerEmail: row.managerEmail || '',
customFields: {
department: row.department || ''
}
});}
importEmployees(employees);return true;}User-Defined Custom Actions
Input:
input.account; uses the account-shaped input from Create User.There is no special helper for custom actions. Most scripts just call the target API with
fetch().
Example: suspend a user in an external system.
function run(context) {var auth = context.get('auth') || {};var input = context.get('input') || {};var account = input.account || {};
if (!account.externalId) {
console.error('Custom action requires input.account.externalId');
return false;}
var response = fetch((auth.baseUrl || '') + '/users/' + account.externalId + '/suspend', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + (auth.token || ''),
'Content-Type': 'application/json'
},
body: JSON.stringify({
reason: 'Suspended from YeshID workflow'
})});
if (!response || !response.ok) {
console.error('Custom action failed', response ? response.status : 'no response');
return false;}
return true;}