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.logconsole.warn, and console.error output. 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() and importGroups(), 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 authinput, 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.baseUrl is the API base URL configured for the integration.

  • Bearer auth provides auth.token.

  • OAuth2 auth provides auth.token, and may also provide auth.tokenTypeauth.headerKey, and auth.headerValuePrefix.

  • API key auth provides auth.apiKeyauth.apiKeyName, and auth.apiKeyLocationauth.apiKeyLocation is HEADER or QUERY.

  • Basic auth provides auth.username and auth.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:

  • accountName

  • externalId

  • extendedInfo

  • roles, with idnameexternalId, and userRequestable

  • user.firstNameuser.lastNameuser.fullNameuser.emailuser.statususer.titleuser.addressuser.startDateuser.endDate

  • user.customFields, keyed by custom field name

  • user.roles

  • user.groups, with idname, and type

  • user.manager, when loaded, with firstNamelastNamefullNameemailstatustitleaddressstartDateendDatecustomFieldsroles, and groups

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 externalIdname, and members. Each member has groupExternalIdmemberExternalId, 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 idnameexternalId, and userRequestable.

fetch(url, options)

Sends a synchronous HTTP request. The response includes statusoktext()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 externalIdemail, 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 input payload; 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; requires input.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; requires input.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: importGroups

  • Helper used inside the script: importGroups([...])

  • Input: no per-group input payload; 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: addToGroup

  • Input: input.account and input.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.account and input.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.account and input.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.account and input.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 input payload; 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;}