workato-sdk-reference
This skill should be used when the user asks about "sdk reference", "actions block reference", "triggers block reference", "object_definitions", "methods block", "pick_lists", "schema block", "http methods workato", "ruby methods workato", or needs API reference documentation for Workato SDK blocks and methods.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install grailautomation-claude-plugins-workato-sdk-reference
Repository
Skill path: workato-sdk/skills/workato-sdk-reference
This skill should be used when the user asks about "sdk reference", "actions block reference", "triggers block reference", "object_definitions", "methods block", "pick_lists", "schema block", "http methods workato", "ruby methods workato", or needs API reference documentation for Workato SDK blocks and methods.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack, Backend.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: grailautomation.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install workato-sdk-reference into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/grailautomation/claude-plugins before adding workato-sdk-reference to shared team environments
- Use workato-sdk-reference for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: workato-sdk-reference
description: This skill should be used when the user asks about "sdk reference", "actions block reference", "triggers block reference", "object_definitions", "methods block", "pick_lists", "schema block", "http methods workato", "ruby methods workato", or needs API reference documentation for Workato SDK blocks and methods.
version: 0.1.0
---
# Workato SDK Reference
Comprehensive reference for all Workato Connector SDK blocks, methods, and configuration options.
## Overview
The Workato SDK consists of these main blocks:
| Block | Purpose |
|-------|---------|
| `connection` | Authentication and base configuration |
| `actions` | Operations users can perform |
| `triggers` | Events that start recipes |
| `methods` | Reusable helper functions |
| `object_definitions` | Reusable schema definitions |
| `pick_lists` | Dropdown options |
| `streams` | Large file handling |
## Connection Block
Defines authentication and connection settings.
```ruby
connection: {
fields: Array, # Credential input fields
authorization: Hash, # Auth type and configuration
base_uri: lambda, # Base URL for requests
test: lambda # Connection test
}
```
### Authorization Types
| Type | Use Case |
|------|----------|
| `basic_auth` | Username/password |
| `api_key` | API key in header/query |
| `oauth2` | OAuth 2.0 flows |
| `custom_auth` | Custom auth logic |
| `multi` | Multiple auth options |
| `aws_auth` | AWS Signature v4 |
## Actions Block
Defines connector operations.
```ruby
actions: {
action_name: {
title: String, # Display name
subtitle: String, # Secondary description
description: lambda, # Dynamic description
help: String | lambda, # Help text
config_fields: Array, # Mode selectors
input_fields: lambda, # Input schema
execute: lambda, # Main logic
output_fields: lambda, # Output schema
sample_output: lambda, # Sample data
retry_on_response: Array, # HTTP codes to retry
retry_on_request: Array, # Errors to retry
max_retries: Integer, # Retry count
summarize_input: Array, # Input summary fields
summarize_output: Array # Output summary fields
}
}
```
### Execute Lambda Parameters
```ruby
execute: lambda do |connection, input, extended_input_schema, extended_output_schema, continue|
# connection - credentials hash
# input - user inputs
# extended_input_schema - dynamic schema info
# extended_output_schema - dynamic output schema
# continue - multistep continuation data
end
```
## Triggers Block
Defines event triggers.
```ruby
triggers: {
trigger_name: {
title: String,
description: lambda,
config_fields: Array,
input_fields: lambda,
poll: lambda, # Polling logic
webhook_subscribe: lambda, # Webhook registration
webhook_unsubscribe: lambda, # Webhook cleanup
webhook_notification: lambda, # Webhook handler
dedup: lambda, # Deduplication
output_fields: lambda,
sample_output: lambda
}
}
```
### Poll Lambda Returns
```ruby
poll: lambda do |connection, input, closure|
{
events: Array, # Records to process
next_poll: Any, # Stored in closure
can_poll_more: Boolean # Continue polling?
}
end
```
## Methods Block
Reusable helper functions.
```ruby
methods: {
method_name: lambda do |arg1, arg2|
# Logic here
end
}
```
### Calling Methods
```ruby
result = call('method_name', arg1, arg2)
```
## Object Definitions Block
Reusable field schemas.
```ruby
object_definitions: {
schema_name: {
fields: lambda do |connection, config_fields, object_definitions|
[
{ name: 'field_name', label: 'Label', type: 'string' }
]
end
}
}
```
### Referencing Object Definitions
```ruby
input_fields: lambda do |object_definitions|
object_definitions['schema_name']
end
```
## Pick Lists Block
Dropdown options.
```ruby
pick_lists: {
# Static list
statuses: lambda do
[
['Active', 'active'],
['Inactive', 'inactive']
]
end,
# Dynamic list
objects: lambda do |connection|
get('/api/objects').map { |o| [o['name'], o['id']] }
end,
# Dependent list
fields: lambda do |connection, object_type:|
get("/api/objects/#{object_type}/fields").map { |f| [f['label'], f['name']] }
end
}
```
## HTTP Methods
### Request Methods
| Method | Usage |
|--------|-------|
| `get(url)` | GET request |
| `post(url)` | POST request |
| `put(url)` | PUT request |
| `patch(url)` | PATCH request |
| `delete(url)` | DELETE request |
### Request Modifiers
```ruby
get('/api/records')
.params(key: 'value') # Query parameters
.payload(data) # Request body
.headers('X-Custom' => 'value') # Custom headers
.request_format_json # JSON body (default)
.request_format_xml # XML body
.request_format_www_form_urlencoded # Form body
.request_format_multipart_form # Multipart body
.response_format_json # Parse JSON (default)
.response_format_xml # Parse XML
.response_format_raw # Raw response
```
### Error Handling
```ruby
get('/api/records')
.after_response do |code, body, headers|
# Handle any response
end
.after_error_response(400) do |code, body, headers, message|
# Handle specific error
end
.after_error_response(/4\d{2}/) do |code, body, headers, message|
# Handle error pattern
end
```
## Field Schema
### Field Properties
| Property | Type | Description |
|----------|------|-------------|
| `name` | String | Internal field name |
| `label` | String | Display label |
| `type` | String | Data type |
| `control_type` | String | UI control |
| `optional` | Boolean | Required field? |
| `default` | Any | Default value |
| `hint` | String | Help text |
| `sticky` | Boolean | Always visible |
| `extends_schema` | Boolean | Triggers schema refresh |
| `ngIf` | String | Conditional visibility |
| `pick_list` | String | Dropdown source |
| `toggle_field` | Hash | Toggle input |
### Data Types
| Type | Description |
|------|-------------|
| `string` | Text (default) |
| `integer` | Whole numbers |
| `number` | Decimal numbers |
| `boolean` | True/false |
| `date` | Date only |
| `date_time` | Date and time |
| `timestamp` | Unix timestamp |
| `object` | Nested object |
| `array` | List of items |
### Control Types
| Control | Use Case |
|---------|----------|
| `text` | Single line text |
| `text-area` | Multi-line text |
| `select` | Dropdown |
| `multiselect` | Multiple selection |
| `number` | Number input |
| `integer` | Integer input |
| `checkbox` | Boolean toggle |
| `password` | Masked input |
| `date` | Date picker |
| `date_time` | DateTime picker |
| `email` | Email input |
| `url` | URL input |
| `phone` | Phone input |
## Ruby Methods
### Workato-Specific Methods
```ruby
workato.log(message) # Debug logging
workato.parse_json(string) # Parse JSON
workato.parse_xml(string) # Parse XML
workato.hmac_sha256(data, key) # HMAC SHA256
workato.jwt_encode(payload, key, alg) # JWT encoding
workato.uuid # Generate UUID
workato.trigger_limit # Current trigger limit
workato.resume_url # Wait-for-resume URL
workato.stream.in(data) # Stream input
workato.stream.out(name, input) # Stream output
```
### Allowed Ruby Methods
Common Ruby methods available in SDK:
- String: `split`, `gsub`, `match`, `strip`, `upcase`, `downcase`
- Array: `map`, `select`, `reject`, `find`, `first`, `last`, `flatten`
- Hash: `dig`, `merge`, `slice`, `except`, `each`, `keys`, `values`
- Time: `now`, `parse`, `iso8601`, `strftime`
- Integer: `to_s`, `to_i`, `abs`, `times`
## Reference Files
For complete documentation:
### Core References
- **`references/sdk-reference.md`** - SDK overview
- **`references/sdk-reference__actions.md`** - Actions reference
- **`references/sdk-reference__triggers.md`** - Triggers reference
- **`references/sdk-reference__connection.md`** - Connection reference
- **`references/sdk-reference__connection__authorization.md`** - Authorization details
### Schema & Methods
- **`references/sdk-reference__schema.md`** - Field schema reference
- **`references/sdk-reference__object_definitions.md`** - Object definitions
- **`references/sdk-reference__methods.md`** - Methods block
- **`references/sdk-reference__picklists.md`** - Pick lists
### HTTP & Utilities
- **`references/sdk-reference__http.md`** - HTTP methods
- **`references/sdk-reference__ruby_methods.md`** - Allowed Ruby methods
- **`references/sdk-reference__streams.md`** - Streaming reference
- **`references/sdk-reference__test.md`** - Testing reference
### Other
- **`references/sdk-reference__custom-action.md`** - Custom action support
- **`references/sdk-reference__whitelist-removal.md`** - Deprecated methods
- **`references/guides.md`** - Guides index
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### references/sdk-reference.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference.html
> **Fetched**: 2026-01-18T02:50:23.360277
---
# [#](<#sdk-reference>) SDK Reference
This is the full list of all possible attributes that you can include in your Workato connector. This section is organized by the root keys of a connector:
* `connection` \- Handles all aspects pertaining to how your connector should establish a connection with a target API.
* `test` \- Works hand in hand with the `connection` key to verify that a connection has been successfully established.
* `actions` \- Contains the definition of all actions in your connector.
* `triggers` \- Contains the definition of all triggers in your connector.
* `object_definitions` \- Define commonly used input or output fields and reference them later on in your actions and triggers.
* `pick_lists` \- Used to generate drop-downs in input fields.
* `methods` \- Create reusable methods which can be called from anywhere in your connector.
* `secure_tunnel` \- Used to created OPA compatible connectors to communicate with on-premise systems.
* `webhook_keys` \- Used in conjunction with Static webhook triggers.
* `streams` \- Used in conjunction with actions and triggers to implement file streaming.
In addition to this, the SDK reference also contains the following information regarding
* Defining input and output fields
* Using HTTP Methods to send requests
* Available ruby methods that can be used in your connector code
## [#](<#sample-connector-skeleton>) Sample Connector Skeleton
Each connector in Workato is a big hash that contains the root keys detailed above. Below, we have an example of a summarized connector. Not all keys are required.
```ruby
{
title: 'My sample connector',
connection: Hash,
test: lambda do
Boolean
end,
custom_action: Boolean,
custom_action_help: Hash,
actions: Hash,
triggers: Hash,
object_definitions: Hash,
pick_lists: Hash,
methods: Hash,
secure_tunnel: Boolean,
webhook_keys: lambda do
String
end,
streams: Hash
}
```
```
### references/sdk-reference__actions.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/actions.html
> **Fetched**: 2026-01-18T02:50:24.506262
---
# [#](<#sdk-reference-actions>) SDK Reference - `actions`
This section enumerates all the possible keys to define an action.
Quick Overview
The `actions` key can only be used in both recipes and the SDK **Test code** tab after you have created a successful connection. Actions receive data from earlier steps in a recipe via datapills, send a request to an endpoint and present the response as datapills.
## [#](<#structure>) Structure
```ruby
actions: {
[Unique_action_name]: {
title: String,
subtitle: String,
description: lambda do |input, picklist_label|
String
end,
help: lambda do |input, picklist_label|
Hash
end,
display_priority: Integer,
batch: Boolean,
bulk: Boolean,
deprecated: Boolean,
config_fields: Array
input_fields: lambda do |object_definitions, connection, config_fields|
Array
end,
execute: lambda do |connection, input, extended_input_schema, extended_output_schema, continue|
Hash
end,
output_fields: lambda do |object_definitions, connection, config_fields|
Array
end,
sample_output: lambda do |connection, input|
Hash
end,
retry_on_response: Array,
retry_on_request: Array,
max_retries: Int,
summarize_input: Array,
summarize_output: Array
},
[Another_unique_action_name]: {
...
}
},
```
* * *
## [#](<#title>) `title`
Attribute | Description
---|---
Key | `title`
Type | String
Required | Optional. Defaults to title built from labeled key.
Description | This allows you to define the title of your action, which might differ from the name of the key assigned to it - Key = `search_object_query`, title = `"Search object via query"`
Expected Output | `String`
i.e. `"Search object via query"`
UI reference | 
TIP
In Workato, we generally advise the following structure "[Verb] [Object]" - "Create lead" or "Search object" rather than "Lead created".
* * *
## [#](<#subtitle>) `subtitle`
Attribute | Description
---|---
Key | `subtitle`
Type | String
Required | Optional. Defaults to subtitle inferred from connector name and action title.
Description | This allows you to define the subtitle of your action.
Expected Output | `String`
i.e. `"Use complex queries to search objects in Percolate"`
UI reference | 
TIP
To make your subtitles meaningful, try to provide more information in here whilst keeping your titles concise. For example, your title could be "Create object" whereas your subtitle could be "Create objects like leads, customers, and accounts in Salesforce." When users search for a specific action, Workato also searches for matches in the subtitle.
* * *
## [#](<#description>) `description`
Attribute | Description
---|---
Key | `description`
Type | lambda function
Required | Optional. Defaults to description inferred from connector name and action title.
Description | This allows you to define the description of your action when viewed in the recipe editor. This can be a static description or a dynamic one based on your needs.
Possible Arguments | `input` \- Hash representing user given inputs defined in `input_fields`
`picklist_label` \- Only applicable for picklists where a user's answer consist of both a picklist label and value. This Hash represents the label for a user's given inputs for picklist fields. See below for use cases.
Expected Output | `String`
i.e. `"Create a <span class='provider'>campaign</span> in <span class='provider'>Percolate</span>"` Add the `<span>` HTML tags to add weight to your description text.
UI reference | 
Example - description:
For the `description` lambda function, you have access to two arguments to make your descriptions dynamic. This is useful when you want to change your description based on how a given user has configured the action. These changes can be incredibly useful for your users to ensure they know what this action is doing without having to click and view the action's configuration to understand what it does.
```ruby
create_object: {
description: lambda do |input, picklist_label|
"Create a <span class='provider'>#{picklist_label['object'] || 'object'}</span> in " \
"<span class='provider'>Percolate</span>"
end,
config_fields: [
{
name: 'object',
control_type: 'select',
pick_list: 'object_types',
optional: false
}
]
# More keys to define the action
}
```
In the preceding example, the action is a generic object action that allows the user to choose between multiple object types when configuring the recipe. You can change the description of the object the user selects by referencing the `picklist_label` argument.

* * *
## [#](<#help>) `help`
Attribute | Description
---|---
Key | `help`
Type | lambda function
Required | Optional. No help is displayed otherwise.
Description | The help text that is meant to guide your users as to how to configure this action. You can also point them to documentation.
Possible Arguments | `input` \- Hash representing user given inputs defined in `input_fields`
`picklist_label` \- Only applicable for picklists where a user's answer consist of both a picklist label and value. This Hash represents the label for a user's given inputs for picklist fields. See below for use cases.
Expected Output | `Hash` or `String` See below for examples.
UI reference | 
Example - help:
The output of the `help` lambda function can either be a simple String or a Hash. Below we go through the two examples:
* String
```ruby
help: lambda do |input, picklist_label|
'Create an object in Percolate. First, select from a list of ' \
'objects that we currently support. After selecting your object,' \
' dynamic input fields specific to your scope and object selected ' \
'will be populated.' \
' Creating an approval denotes submitting a specified piece of content' \
' or campaign for a specific approval workflow.'
end,
```
* Hash
```ruby
help: lambda do |input, picklist_label|
{
body: "First, filter by the object you want then fill up the input fields " \
"which appear based on the object you have selected. Amongst other things, " \
"you’ll be able to search for contacts in your company and cloud recordings from the past. ",
learn_more_url: "https://docs.workato.com/connectors/zoom/event-actions.html#search-event-details",
learn_more_text: "Learn more"
}
end,
```

* * *
## [#](<#display-priority>) `display_priority`
Attribute | Description
---|---
Key | `display_priority`
Type | Integer
Required | Optional. Defaults to zero, otherwise to the alphabetical ordering of actions titles.
Description | This allows you to influence the ordering of the action in the recipe editor so that you can highlight top actions. The higher the integer, the higher the priority. If two actions have the same priority, they are ordered by their titles.
* * *
## [#](<#batch>) `batch`
Attribute | Description
---|---
Key | `batch`
Type | Boolean
Required | Optional.
Description | This presents a "Batch" tag next to your action to indicate that this action works with multiple records. Normally used in batch triggers or batch create/update/upsert actions where users can pass a list of records.
UI reference | 
* * *
## [#](<#bulk>) `bulk`
Attribute | Description
---|---
Key | `bulk`
Type | Boolean
Required | Optional.
Description | This presents a "Bulk" tag next to your action to indicate that this action works with a large flat file of records. Normally used bulk create/update/upsert actions where users pass a CSV of records.
UI reference | 
* * *
## [#](<#deprecated>) `deprecated`
Attribute | Description
---|---
Key | `deprecated`
Type | Boolean
Required | Optional.
Description | This presents a "deprecated" tag next to your action to indicate that this action has been deprecated. Recipes which used to use this action will continue to work but future recipes will not be able to search and select this action.
UI reference | 
TIP
Deprecation is a great way to move users to new actions when changes are not backwards compatible. This gives you more freedom to make your actions more usable or cater for upcoming API changes.
* * *
## [#](<#config-fields>) `config_fields`
Attribute | Description
---|---
Key | `config_fields`
Type | Array
Required | Optional.
Description | This key accepts an array of hashes which show up as input fields shown to a user. Config fields are shown to a user before input fields are rendered and can be used to alter what set of input fields are shown to an end user. This is often used in generic object actions where config fields prompt a user to select the object and input fields are rendered based on that selection. To know more about how to define config fields in Workato, click [here.](</developing-connectors/sdk/sdk-reference/schema.html>)
Expected Output | Array of hashes. Each hash in this array corresponds to a separate config field.
UI reference | 
TIP
Config fields are powerful tools to introduce dynamic behavior to your actions. Use them to make your connector easier to use and discover new features. In the example gif above, you can see that the input "Event" actually causes more input fields to render. These input fields are rendered based on the selection of the value "Meeting".
* * *
## [#](<#input-fields>) `input_fields`
Attribute | Description
---|---
Key | `input_fields`
Type | lambda function
Required | True
Description | This lambda function allows you to define what input fields should be shown to a user configuring this action in the recipe editor. Output of this lambda function should be an array of hashes, where each hash in this array corresponds to a separate input field. To know more about how to define input fields in Workato, click [here.](</developing-connectors/sdk/sdk-reference/schema.html>)
Possible Arguments | `object_definitions` \- Allows you to reference an object definitions. Object definitions are stores of these arrays hashes which may be used to represent both input fields or output fields (datapills). These can be referenced by any action or trigger.
`connection` \- Hash representing user given inputs defined in `connection`.
`config_fields` \- Hash representing user given inputs defined in `config_fields`, if applicable.
Expected Output | Array of hashes. Each hash in this array corresponds to a separate input field.
UI reference | 
* * *
## [#](<#execute>) `execute`
Attribute | Description
---|---
Key | `execute`
Type | lambda function
Required | True
Description | This lambda function allows you to define what this action does with the inputs that have been passed to it from an end user. These inputs may be static values or datapills from upstream actions or the trigger. These are then used to send a HTTP request to retrieve data that can be presented as datapills.
Optionally, you can also use the execute lambda function to do any pre-processing of input data before sending it as a request and post-processing of response data before passing it out as datapills.
Possible Arguments | `connection` \- Hash representing user given inputs defined in `Connection`
`input` \- Hash representing user given inputs defined in `input_fields`
`extended_input_schema` \- See below for examples.
`extended_output_schema` \- See below for examples
`continue` \- Hash representing cursor from the previous invocation of execute. OPTIONAL and used for asynchronous actions. See below for examples.
Expected Output | Hash representing the data to be mapped to the output datapills of this action.
Example - execute: - extended_input_schema and extended_output_schema
Extended input and output schema is any schema from `object_definitions` that is used in your action. This information is often useful when you dynamically generate schema and you want to use it to do data pre- or post-processing. These arguments do not include config_fields.
For example, you may use extended_input_schema to know which inputs are datetimes and should be transformed to Epoch time which is accepted by the target API. In the same fashion, you may use extended_output_schema to take the response and transform Epoch variables into ISO8601 datetimes again.
```ruby
create_object: {
description: lambda do |input, picklist_label|
"Create a <span class='provider'>#{picklist_label['object'] || 'object'}</span> in " \
"<span class='provider'>Percolate</span>"
end,
config_fields: [
{
name: 'object',
control_type: 'select',
pick_list: 'object_types',
optional: false
}
],
input_fields: lambda do |object_definitions, connection, config_fields|
object = config_fields['object']
object_definitions[object].ignored('id')
end,
execute: lambda do |connection, input, extended_input_schema, extended_output_schema|
puts extended_input_schema
# [
# {
# "type": "string",
# "name": "status",
# "control_type": "select",
# "label": "Status",
# "hint": "Status is required for creating Content",
# "pick_list": "post_statuses",
# "optional": false
# },
# ...
# ]
puts extended_output_schema
# [
# {
# "type": "string",
# "name": "id",
# "control_type": "text",
# "label": "Content ID",
# "hint": "The Content ID, Example: <b>post:45565410</b>.",
# "optional": true
# },
# {
# "type": "string",
# "name": "status",
# "control_type": "select",
# "label": "Status",
# "hint": "Status is required for creating Content",
# "pick_list": "post_statuses",
# "optional": false
# },
# ...
# ]
end,
output_fields: lambda do |object_definitions, connection, config_fields|
object = config_fields['object']
object_definitions[object]
end,
}
```
Example - execute: - continue
When working with asynchronous APIs to kickstart a long running job or process in a target application, often times you'll send a request and expect an ID that corresponds to that job or process. Your action would then want to constantly check back with the API to see if the job is completed before retrieving results or moving on to the next step in the recipe.
For example, when you send a request to Google BigQuery to start a query, Google BigQuery might send you back the job ID. Your task would be to now regularly check back with Google BigQuery to see if the query is completed before retrieving the rows.
Rather than having the user configure this logic in the recipe, you can now embed this entire logic into a single action with "multi-step" actions on your custom connector. To use "multi-step" actions, the `continue` argument is used in conjunction with a dedicated method called `reinvoke_after`. Below, we go through some examples of what the `continue` argument might be.
To learn more about creating your "multistep" actions, read our guide [here](</developing-connectors/sdk/guides/building-actions/multistep-actions.html>).
```ruby
multistep_action_sample: {
input_fields: lambda do |object_definitions, connection, config_fields|
end,
execute: lambda do |connection, input, e_i_s, e_o_s, continue|
if !continue.present? #continue is nil on the first invocation of the execute
puts continue
# nil
reinvoke_after(seconds: 100, continue: { current_step: 1 })
elsif continue['current_step'] == 1 #first reinvocation
puts continue
# {
# "current_step": 1
# }
reinvoke_after(seconds: 100, continue: { current_step: continue['current_step'] + 1 })
else
puts continue
# {
# "current_step": 2
# }
end
end,
output_fields: lambda do |object_definitions, connection, config_fields|
end,
}
```
* * *
## [#](<#before-suspend>) `before_suspend`
Attribute | Description
---|---
Key | `before_suspend`
Type | lambda function
Required | False
Description | This lambda function is exclusive to [Wait for resume actions](</developing-connectors/sdk/guides/building-actions/wait-for-resume-actions.html>). It is invoked after the `suspend` method is called in the `execute` lambda. It allows you to define an authenticated API request based on the `apply` to an external system to register a callback to resume the job.
Possible arguments |
* `resume_token`: This token is specific to a particular job and is generated by the Workato framework. When the external system intends to resume a job, it must include this token in its resume request to the Resume job API.
* `expires_at`: Timestamp in PST representing the time the job expires and resumes with a timeout.
* `continue`: The `continue` hash passed from the `suspend` method. This can contain important information including the ID of the process in the external system.
Expected output | N/A
* * *
## [#](<#before-resume>) `before_resume`
Attribute | Description
---|---
Key | `before_resume`
Type | lambda function
Required | False
Description | This lambda function is exclusive to [Wait for resume actions](</developing-connectors/sdk/guides/building-actions/wait-for-resume-actions.html>). It is invoked after the external system has dispatched the API request to resume the job. It enables you to control the state of the `continue` hash, which is transmitted back to the `execute` lambda when the job resumes. Additionally, it grants access to the data value in the API request.
Possible arguments |
* `data`: This represents the `data` value in the API request to resume the job.
* `input`: The input that the recipe sends directly to the action.
* `continue`: The `continue` hash passed from the `suspend` method. This can contain important information, including the ID of the process in the external system.
Expected output | N/A
However, the lambda allows you to edit the value of the `continue` hash.
Example- Edit the value of the continue hash
This example demonstrates how to edit the value of the `continue` hash.
If the `continue` method passed from the `suspend` method is:
```ruby
{
"state": "suspended",
"job_id": "abc_123"
}
```
and the `before_resume` lambda is:
```ruby
before_resume: lambda do |data, input, continue|
if continue["state"] == "suspended"
continue["state"] = "resumed"
continue["payload"] = "important data"
else
{ "result" => "Unexpected state" }
end
end,
```
Then the `continue` argument passed to the `execute` lambda looks like this:
```ruby
{
"state": "resumed",
"job_id": "abc_123",
"payload": "important data"
}
```
* * *
## [#](<#before-timeout-resume>) `before_timeout_resume`
Attribute | Description
---|---
Key | `before_timeout_resume`
Type | lambda function
Required | False
Description | This lambda function is exclusive to [Wait for resume actions](</developing-connectors/sdk/guides/building-actions/wait-for-resume-actions.html>). It is invoked when the `expires_at` time has passed and Workato has not received an API request to resume the job. It allows you to manage the state of the `continue` hash which is passed back to the `execute` lambda when the job resumes.
Possible arguments |
* `input`: The input that the recipe sends directly to the action.
* `continue`: The `continue` hash passed from the `suspend` method. This can contain important information, including the ID of the process in the external system.
Expected output | N/A
However, the lambda allows you to edit the value of the `continue hash`. Refer to the `before_resume` example to learn more.
* * *
## [#](<#output-fields>) `output_fields`
Attribute | Description
---|---
Key | `output_fields`
Type | lambda function
Required | True
Description | This lambda function allows you to define what output fields (datapills) should be shown to a user configuring this action in the recipe editor. The output of this lambda function should be an array of hashes, where each hash in this array corresponds to a separate output field (datapill). To know more about how to define input fields in Workato, click [here.](</developing-connectors/sdk/sdk-reference/schema.html>)
Possible Arguments | `object_definitions` \- Allows you to reference an object definitions. Object definitions are stores of these arrays which can represent either input and output fields. These can be referenced by any action or trigger.
`connection` \- Hash representing user given inputs defined in `connection`.
`config_fields` \- Hash representing user given inputs defined in `config_fields`, if applicable.
Expected Output | Array of hashes. Each hash in this array corresponds to a separate input field.
UI reference | 
Example - output_fields:
Output fields relate directly to the datapills that users see in the recipe editor. The definition of these output fields are mapped to the output of the `execute` lambda function which is a hash.
```ruby
create_object: {
execute: lambda do |connection, input, extended_input_schema, extended_output_schema|
post("/object/create", input)
# JSON response passed out of the execute: lambda function.
# {
# "id": 142414,
# "title": "Newly created object",
# "description": "This was created via an API"
# }
end,
output_fields: lambda do |object_definitions, connection, config_fields|
[
{
name: "id",
type: "integer"
},
{
name: "title",
type: "string"
},
{
name: "description",
type: "string"
}
]
end,
}
```
* * *
## [#](<#sample-output>) `sample_output`
Attribute | Description
---|---
Key | `sample_output`
Type | lambda function
Required | False.
Description | This lambda function allows you to define a sample output that is displayed next to your output fields (datapills).
Possible Arguments | `connection` \- Hash representing user given inputs defined in `connection`.
`input` \- Hash representing user given inputs defined in `input_fields`
Expected Output | Hash. This hash should be a stubbed output of the `execute` lambda function.
UI reference | 
* * *
## [#](<#retry-on-response>) `retry_on_response`
Attribute | Description
---|---
Key | `retry_on_response`
Type | Array
Required | False.
Description | **Used in conjunction with retry_on_request: and max_retries:**
Use this declaration to implement a retry mechanism for certain HTTP methods and responses. This guards against APIs which may sometime return errors due to server failure such as 500 Internal Server Error codes.
When supplying this array, we will accept what error codes to retry on as well as entire string or regex expressions.
In cases where no error code is defined, Workato will only search the message body for any given regex or plain string IF the error codes fall under a default list of codes: (429, 500, 502, 503, 504, 507). When supplying an entire string instead of regex, this will give only retry if the entire response matches exactly.
If entire strings or regex match and error codes are defined, both the error codes and strings must match for retries to be triggered
Expected Output | Array. For example, `[500]` or `[500,/error/]` or `[‘“error”’, 500]`
* * *
## [#](<#retry-on-request>) `retry_on_request`
Attribute | Description
---|---
Key | `retry_on_request`
Type | Array
Required | False.
Description | **Used in conjunction with retry_on_request: and max_retries:**
Use this declaration to implement a retry mechanism for certain HTTP methods and responses. This guards against APIs which may sometime return errors due to server failure such as 500 Internal Server Error codes.
Optional. When not defined, it defaults to only “GET” and “HEAD” HTTP requests.
Expected Output | Array. For example, `[“GET”]` or `[“GET”, “HEAD”]`
* * *
## [#](<#max-retries>) `max_retries`
Attribute | Description
---|---
Key | `max_retries`
Type | Int
Required | False.
Description | **Used in conjunction with retry_on_request: and max_retries:**
Use this declaration to implement a retry mechanism for certain HTTP methods and responses. This guards against APIs which may sometime return errors due to server failure such as 500 Internal Server Error codes.
The number of retries. A maximum of 3 allowed. If more than 3, action retries 3 times.
Workato waits 5 seconds for the first retry and increases the interval by 5 seconds for each subsequent retry.
Expected Output | Int. For example, `1` or `2`
TIP
* We recommend using only one HTTP method per action if possible
* Multiple GET requests within a single action are also possible
* Since we retry on an action level, actions should be defined to only at most only one POST request. This guards against cases where the first post request succeeds and the second post request fails.
Example - Implementing the retry mechanism
Retrying an API request is very useful in ensuring that your actions (and recipes) are tolerant to any inconsistencies in the target App. To implement this, you will need to use a combination of the retry_on_response:, retry_on_request: and max_retries: keys.
```ruby
actions: {
custom_http: {
input_fields: lambda do |object_definitions|
[{ name: 'url', optional: false }]
end,
execute: lambda do |_connection, input|
{
results: get(input['url'])
}
end,
output_fields: lambda do |object_definitions|
[]
end,
retry_on_response: [500, /error/] # contains error codes and error message match rules
retry_on_request: ["GET", "HEAD"],
max_retries: 3
}
}
```
* * *
## [#](<#summarize-input>) `summarize_input`
Attribute | Description
---|---
Key | `summarize_input`
Type | Array
Required | False.
Description | Use this to summarize your input which contain long lists. Summarizing your input is important to keep the jobs page lightweight so it can load quickly. In general, when your input has lists that are longer than 100 lines, they should be summarized.
Expected Output | Array. For example, `['leads']` or `['report.records', 'report.description']`
* * *
## [#](<#summarize-output>) `summarize_output`
Attribute | Description
---|---
Key | `summarize_output`
Type | Array
Required | False.
Description | Use this to summarize your actions output which contain long lists. Summarizing your output is important to keep the jobs page lightweight so it can load quickly. In general, when your output has lists that are longer than 100 lines, they should be summarized.
Expected Output | Array. For example, `['leads']` or `['report.records', 'report.description']`
UI reference | 
Example - Summarizing inputs and outputs in job data
When working with large arrays or data, Workato tries to show all the data in the input and output tabs of the job for each action. Sometimes, this can get confusing when we are working with a large numbers of records or large strings. You can use the `summarize_input` and `summarize_output` keys to summarize the data in your job input and output tabs to make it more human readable for users of your connector.
```ruby
input_fields: lambda do
[
{
name: 'report',
type: 'object',
properties: [
{
name: 'records',
type: :array,
of: :object,
properties: [
{
name: 'item_name',
type: 'string'
}
]
},
{
name: 'description',
type: 'string'
},
{
name: 'comment',
type: 'string'
}
],
}
]
end,
summarize_input: ['report.records', 'report.description'],
```
```
### references/sdk-reference__triggers.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/triggers.html
> **Fetched**: 2026-01-18T02:50:38.783997
---
# [#](<#sdk-reference-triggers>) SDK Reference - `triggers`
This section enumerates all the possible keys to define a trigger. There are 3 types of triggers available for you to use in Workato:
* Polling triggers (Check for new events every 5 minutes)
* Dynamic webhook triggers (Triggers in real time from webhooks. Programmatic subscription and teardown of webhook URLs must be possible in the App)
* Static webhook triggers (Triggers in real time from webhooks. Webhook URLs are passed from Workato to App by the end user.)
Quick Overview
The `triggers` key can only be used in both recipes and the SDK **Test code** tab after you have created a successful connection. Triggers are configured by end users of your connector and kick start recipes.
## [#](<#structure>) Structure
```ruby
triggers: {
[Unique_trigger_name]: {
title: String,
subtitle: String,
description: lambda do |input, picklist_label|
String
end,
help: lambda do |input, picklist_label|
Hash
end,
display_priority: Integer,
batch: Boolean,
bulk: Boolean,
deprecated: Boolean,
config_fields: Array
input_fields: lambda do |object_definitions, connection, config_fields|
Array
end,
webhook_key: lambda do |connection, input|
String
end,
webhook_response_type: String,
webhook_response_body: String,
webhook_response_headers: String,
webhook_response_status: Integer,
webhook_payload_type: String,
webhook_subscribe: lambda do |webhook_url, connection, input, recipe_id|
Hash or Array
end,
webhook_refresh: lambda do |webhook_subscribe_output|
Array
end,
webhook_unsubscribe: lambda do |webhook_subscribe_output, connection|
Hash
end,
webhook_notification: lambda do |input, payload, extended_input_schema, extended_output_schema, headers, params, connection, webhook_subscribe_output|
Hash or Array
end,
poll: lambda do |connection, input, closure|
Hash
end,
dedup: lambda do |record|
String
end,
output_fields: lambda do |object_definitions, connection, config_fields|
Array
end,
sample_output: lambda do |connection, input|
Hash
end,
summarize_input: Array,
summarize_output: Array
},
[Another_unique_trigger_name]: {
...
}
},
```
* * *
## [#](<#title>) `title`
Attribute | Description
---|---
Key | `title`
Type | String
Required | Optional. Defaults to title built from labeled key.
Description | This allows you to define the title of your trigger, which might differ from the name of the key assigned to it - Key = `new_updated_object`, title = `"New/updated object"`
Expected Output | `String`
i.e. `"New/updated object"`
UI reference | 
TIP
In Workato, we generally advise the following structure for triggers "[Adjective] [Object]" - "New lead" or "New/updated contact" rather than "Lead created".
* * *
## [#](<#subtitle>) `subtitle`
Attribute | Description
---|---
Key | `subtitle`
Type | String
Required | Optional. Defaults to subtitle inferred from connector name and trigger title.
Description | This allows you to define the subtitle of your trigger.
Expected Output | `String`
i.e. `"Use complex queries to search objects in Percolate"`
UI reference | 
TIP
To make your subtitles meaningful, try to provide more information in here whilst keeping your titles concise. For example, your title could be "New/updated object" whereas your subtitle could be "Trigger off new/updated leads, contacts etc." When users search for a specific triggers, Workato also searches for matches in the subtitle.
* * *
## [#](<#description>) `description`
Attribute | Description
---|---
Key | `description`
Type | lambda function
Required | Optional. Defaults to description inferred from connector name and trigger title.
Description | This allows you to define the description of your trigger when viewed in the recipe editor. This can be a static description or a dynamic one based on your needs.
Possible Arguments | `input` \- Hash representing user given inputs defined in `input_fields`
`picklist_label` \- Only applicable for picklists where a user's answer consist of both a picklist label and value. This Hash represents the label for a user's given inputs for picklist fields. See below for use cases.
Expected Output | `String`
i.e. `"New or updated <span class='provider'>campaign</span> in <span class='provider'>Percolate</span>"` Add the `<span>` HTML tags to add weight to your description text.
UI reference | 
Example - description:
For the `description` block, you have access to two arguments to make your descriptions dynamic. This is useful when you want to change your description based on how a given user has configured the action. These changes can be incredibly useful for your users to ensure they know what this action is doing without having to click and view the action's configuration to understand what it does.
```ruby
new_updated_object: {
description: lambda do |input, picklist_label|
"New or updated <span class='provider'>#{picklist_label['object'] || 'object'}</span> in " \
"<span class='provider'>Percolate</span>"
end,
config_fields: [
{
name: 'object',
control_type: 'select',
pick_list: 'object_types',
optional: false
}
]
# More keys to define the action
}
```
In the preceding example, the action is a generic object action that allows the user to choose between multiple object types when configuring the recipe. You can change the description of the object the user selects by referencing the `picklist_label` argument.

* * *
## [#](<#help>) `help`
Attribute | Description
---|---
Key | `help`
Type | lambda function
Required | Optional. No help is displayed otherwise.
Description | The help text that is meant to guide your users as to how to configure this trigger. You can also point them to documentation.
Possible Arguments | `input` \- Hash representing user given inputs defined in `input_fields`
`picklist_label` \- Only applicable for picklists where a user's answer consist of both a picklist label and value. This Hash represents the label for a user's given inputs for picklist fields. See below for use cases.
`connection` \- Hash representing user given inputs defined in `connection`.
`webhook_base_url` \- Used when you are using [static webhook triggers](</developing-connectors/sdk/guides/building-triggers/static-webhook.html>). String representing the static webhook url of your connector.
Expected Output | `Hash` or `String` See below for examples.
UI reference | 
Example - help:
The output of the `help` lambda function can either be a simple String or a Hash. Below we go through the two examples:
* String
```ruby
help: lambda do |input, picklist_label, connection, webhook_base_url|
'Create an object in Percolate. First, select from a list of ' \
'objects that we currently support. After selecting your object,' \
' dynamic input fields specific to your scope and object selected ' \
'will be populated.' \
' Creating an approval denotes submitting a specified piece of content' \
' or campaign for a specific approval workflow.'
end,
```
* Hash
```ruby
help: lambda do |input, picklist_label, connection, webhook_base_url|
{
body: "First, filter by the object you want then fill up the input fields " \
"which appear based on the object you have selected. Amongst other things, " \
"you’ll be able to search for contacts in your company and cloud recordings from the past. ",
learn_more_url: "https://docs.workato.com/connectors/zoom/event-actions.html#search-event-details",
learn_more_text: "Learn more"
}
end,
```

Example - Static webhook triggers - Using connection and inputs to create a Unique webhook URL
When you may have a single connector and static webhook url that needs to power multiple recipes across multiple connections, you might need your users to register webhook URLs that contain attributes specific to their connections. You can now do this through the `help` lambda where you can provide a webhook URL for your users to register that include any connection attributes within the webhook's URL parameters.
```ruby
{
title: "Sample connector",
webhook_keys: lambda do |params, headers, payload|
"#{params['org_id']}@#{payload['formId']}"
end,
triggers: {
sample_static_webhook_trigger: {
help: lambda do |input, picklist_label, connection, webhook_base_url|
next unless webhook_base_url.present?
<<~HTML
Creates a job when an form submission is received. To set this webhook up,
'you will need to register the webhook below under "settings" => "webhooks" => "new". <br>
<b>Webhook endpoint URL</b>
<b class="tips__highlight">#{webhook_base_url}?org_id=#{connection['org_id']}</b>
HTML
end,
webhook_key: lambda do |connection, input|
"#{connection['org_id']}@#{input['formId']}"
end,
input_fields: lambda do |object_definitions, connection, config_fields|
[
{
name: 'formId',
label: "Form",
control_type: "select",
pick_list: "forms",
hint: "Select the form you want to trigger this recipe off."
}
]
end,
}
}
}
```
* * *
## [#](<#display-priority>) `display_priority`
Attribute | Description
---|---
Key | `display_priority`
Type | Integer
Required | Optional. Defaults to zero, otherwise to the alphabetical ordering of actions titles.
Description | This allows you to influence the ordering of the trigger in the recipe editor so that you can highlight top triggers. The higher the integer, the higher the priority. If two triggers have the same priority, they are ordered by their titles.
* * *
## [#](<#batch>) `batch`
Attribute | Description
---|---
Key | `batch`
Type | Boolean
Required | Optional.
Description | This presents a "Batch" tag next to your action to indicate that this action works with multiple records. Normally used in batch triggers or batch create/update/upsert actions where users can pass a list of records.
UI reference | 
* * *
## [#](<#bulk>) `bulk`
Attribute | Description
---|---
Key | `bulk`
Type | Boolean
Required | Optional.
Description | This presents a "Bulk" tag next to your action to indicate that this action works with a large flat file of records. Normally used bulk create/update/upsert actions where users pass a CSV of records.
UI reference | 
* * *
## [#](<#deprecated>) `deprecated`
Attribute | Description
---|---
Key | `deprecated`
Type | Boolean
Required | Optional.
Description | This presents a "deprecated" tag next to your action to indicate that this action has been deprecated. Recipes which used to use this action will continue to work but future recipes will not be able to search and select this action.
UI reference | 
TIP
Deprecation is a great way to move users to new actions when changes are not backwards compatible. This gives you more freedom to make your actions more usable or cater for upcoming API changes.
* * *
## [#](<#config-fields>) `config_fields`
Attribute | Description
---|---
Key | `config_fields`
Type | Array
Required | Optional.
Description | This key accepts an array of hashes which show up as input fields shown to a user. Config fields are shown to a user before input fields are rendered and can be used to alter what set of input fields are shown to an end user. This is often used in generic object actions where config fields prompt a user to select the object and input fields are rendered based on that selection. Inputs given to `config_fields` can be referenced by the connector in the `input_fields` lambda function via an argument. It is also present as an argument in all `object_defintions`. To know more about how to define config fields in Workato, click [here.](</developing-connectors/sdk/sdk-reference/schema.html>)
Expected Output | Array of hashes. Each hash in this array corresponds to a separate config field.
UI reference | 
TIP
Config fields are powerful tools to introduce dynamic behavior to your actions. Use them to make your connector easier to use and discover new features. In the example gif above, you can see that the input "Event" actually causes more input fields to render. These input fields are rendered based on the selection of the value "Meeting".
* * *
## [#](<#input-fields>) `input_fields`
Attribute | Description
---|---
Key | `input_fields`
Type | lambda function
Required | True
Description | This lambda function allows you to define what input fields should be shown to a user configuring this trigger in the recipe editor. Output of this lambda function should be an array of hashes, where each hash in this array corresponds to a separate input field. To know more about how to define input fields in Workato, click [here.](</developing-connectors/sdk/sdk-reference/schema.html>)
Possible Arguments | `object_definitions` \- Allows you to reference an object definitions. Object definitions are stores of these arrays hashes which may be used to represent both input fields or output fields (datapills). These can be referenced by any action or trigger.
`connection` \- Hash representing user given inputs defined in `connection`.
`config_fields` \- Hash representing user given inputs defined in `config_fields`, if applicable.
Expected Output | Array of hashes. Each hash in this array corresponds to a separate input field.
UI reference | 
* * *
## [#](<#webhook-key>) `webhook_key`
Attribute | Description
---|---
Key | `webhook_key`
Type | lambda function
Required | True if trigger is a static webhook trigger. False otherwise. Should not be used when `webhook_subscribe`, `webhook_unsubscribe` is defined.
Description | **Used in conjunction with`webhook_keys` which should be present as a root level key in the connector - same level as `actions` and `triggers`**
Allows you to use any user input from the connection or trigger to build a unique signature for this trigger. This can also be a static string value. When the signature in this lambda function match the signature in the `webhook_keys` lambda function, webhooks are sent to this trigger. See our [Static webhook guide for more details.](</developing-connectors/sdk/guides/building-triggers/static-webhook.html>)
Possible Arguments | `connection` \- Hash representing user given inputs defined in `connection`.
`input` \- Hash representing user given inputs defined in `input_fields`
Expected Output | Array of hashes. Each hash in this array corresponds to a separate input field.
Example - webhook_key:
The `webhook_key` lambda function is specific to a single trigger and the output signature if built from user inputs. On the other hand, the `webhook_keys` lambda function is tied to the entire connector and the output signature is built from the incoming webhook's attributes like its body, headers, and query parameters. When expecting a match in these two signature, it becomes easy to see how routing is done from incoming webhooks to the proper trigger to create jobs.
```ruby
{
title: "Sample connector",
webhook_keys: lambda do |params, headers, payload|
payload['formId']
end,
triggers: {
sample_static_webhook_trigger: {
help: lambda do |_input, _picklist_label|
{
body: “Triggers in real-time whenever an event is created. Set up this trigger by registering the Webhook URL ” \
“below in <b>Settings</b> => <b>Webhooks</b>.“,
learn_more_url: “https://docs.workato.com”,
learn_more_text: “Learn more”
}
end,
webhook_url_help: lambda do |_connection, _input, webhook_base_url|
webhook_base_url
end,
input_fields: lambda do |object_definitions, connection, config_fields|
[
{
name: 'formId',
label: "Form",
control_type: "select",
pick_list: "forms",
hint: "Select the form you want to trigger this recipe off."
}
]
end,
webhook_key: lambda do |connection, input|
input['formId']
end,
}
}
}
```
* * *
## [#](<#webhook-response-type>) `webhook_response_type`
Attribute | Description
---|---
Key | `webhook_response_type`
Type | String
Required | Optional. Only applies to Dynamic webhook triggers ( triggers with `webhook_subscribe` and `webhook_unsubscribe`)
Description | By default, Workato responds with no content-type headers to webhook events. `webhook_response_type` allows for 'plain' and 'json' which corresponds to content-type headers `text/plain` and `application/json` respectively.
* * *
## [#](<#webhook-response-body>) `webhook_response_body`
Attribute | Description
---|---
Key | `webhook_response_body`
Type | String
Required | Optional. Only applies to Dynamic webhook triggers ( triggers with `webhook_subscribe` and `webhook_unsubscribe`)
Description | By default, Workato responds with an empty body to webhook events. `webhook_response_body` allows for a mustache template that allows you to define how Workato should respond to webhooks.
Mustache templates have access to the following variables:
name | description | example usage
---|---|---
headers | Contains request headers. Headers are normalized (x–custom-header -> X-Custom-Header) | ` { “challenge”:“{{{headers.X-Challenge}}}” } `
body | Request body is parsed according to the `webhook_response_type`. You can use dot notation to access nested values. | ` { “challenge”: “{{body.x-challenge}}” } `
query | Contains query params | ` { “X-Challenge”: “{{query.challenge}}” } `
Example - webhook_response_body: - Defining a custom webhook response
Use `webhook_response_body` in two scenarios:
1. You need to respond with a static string or JSON response to the webhook sender.
```ruby
webhook_response_type: 'json',
webhook_response_body: '{ "success": true }',
```
will result in Workato responding with a content-type `application/json` and the body
```ruby
{
"success": true
}
```
2. You need to respond with a dynamic response based on the webhook event. For example, when webhook senders send a webhook event to confirm that the webhook URL is ready.
```ruby
webhook_response_type: 'json',
webhook_response_body: '{ “challenge”: “{{body.verification.Challenge}}” }',
```
If the sender sends a webhook with the body
```ruby
{
"verification": {
"Challenge": "abc123"
}
}
```
Then Workato would respond with
```ruby
{
"challenge": "abc123"
}
```
In some cases, webhook senders may also send an array of events. You may also use regular iterators in Mustache to work with arrays.
For example, if the sender (based on Microsoft Event Grid)sends a webhook validation event with the body
```ruby
[
{
"id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66",
"topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"subject": "",
"data": {
"validationCode": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6",
"validationUrl": "https://rp-eastus2.eventgrid.azure.net:553/eventsubscriptions/myeventsub/validate?id=0000000000-0000-0000-0000-00000000000000&t=2022-10-28T04:23:35.1981776Z&apiVersion=2018-05-01-preview&token=1A1A1A1A"
},
"eventType": "Microsoft.EventGrid.SubscriptionValidationEvent",
"eventTime": "2022-10-28T04:23:35.1981776Z",
"metadataVersion": "1",
"dataVersion": "1"
}
]
```
and expects us to respond with the `data.validationCode`. You may define your `webhook_response_body` as such.
```ruby
webhook_response_type: 'json',
webhook_response_body: '{{#body}}{ "validationResponse": “{{data.validationCode}}” }{{/body}}',
```
There may be a variety of situations where webhook senders may expect custom responses:
1. Static or dynamic responses for each webhook event
2. Responding to a challenge to confirm the webhook URL is ready to accept events
In our investigation, we have rarely found both to be the case. As such, this singular key `webhook_response_body` aims to accomplish both use cases. You may also use inbuilt logic such as [inverted sections (opens new window)](<https://mustache.github.io/mustache.5.html#Inverted-Sections>) in mustache templates for greater control over the webhook responses.
* * *
## [#](<#webhook-response-headers>) `webhook_response_headers`
Attribute | Description
---|---
Key | `webhook_response_headers`
Type | String
Required | Optional. Only applies to Dynamic webhook triggers ( triggers with `webhook_subscribe` and `webhook_unsubscribe`)
Description | By default, Workato responds with an standard headers (rate limit, byte limit) to webhook events. `webhook_response_headers` allows for a mustache template that allows you to define what headers Workato should include in response headers. See [webhook_response_body](<#webhook-response-body>)
WARNING
Workato only supports customization of headers starting with `x-` with the exception of `x-forwarded-host`, `x-forwarded-proto`, `x-forwarded-port`, `x-forwarded-for`, `x-request-id`, `x-frame-options` and `x-powered-by`.
* * *
## [#](<#webhook-response-status>) `webhook_response_status`
Attribute | Description
---|---
Key | `webhook_response_status`
Type | Integer
Required | Optional. Only applies to Dynamic webhook triggers ( triggers with `webhook_subscribe` and `webhook_unsubscribe`)
Description | By default, Workato responds with 200 to webhook events. `webhook_response_status` allow you to customize this to any 2XX response codes.
WARNING
Workato only supports customization 2XX response codes.
* * *
## [#](<#webhook-payload-type>) `webhook_payload_type`
Attribute | Description
---|---
Key | `webhook_payload_type`
Type | String
Required | Optional. Defaults to "parsed"
Description | By default, Workato parses incoming webhook payloads using [JSON.parse() (opens new window)](<https://ruby-doc.org/stdlib-2.6.3/libdoc/json/rdoc/JSON.html#method-i-parse>). Setting `webhook_payload_type` to "raw" allows you to receive the raw webhook payload instead of a JSON parsed one.
Example - webhook_payload_type: - Verifying webhooks or handling XML webhooks
Use `webhook_payload_type` in two scenarios:
1. You need to compute a webhook payload signature based on the **raw** payload. You may do so in the webhook notification lambda before using `workato.parse_json` to get the parsed json payload.
```ruby
webhook_payload_type: "raw",
webhook_notification: lambda do |input, payload, extended_input_schema, extended_output_schema, headers, params, connection, webhook_subscribe_output|
original_payload = payload
client_secret = input['client_secret'] || account_property('hubspot_webhook_client_secret')
if client_secret.present?
source_string = client_secret + original_payload
v1_signature = source_string.encode_sha256.encode_hex
end
if (client_secret.present? && v1_signature == headers['X-Hubspot-Signature']) || !client_secret.present?
payload = workato.parse_json(payload).select do |event|
event['propertyName'] == input['contact_property'] && event['subscriptionType'] == 'contact.propertyChange'
end
if payload.length > 0
{
events: payload,
headers: headers,
webhook_validated: client_secret.present? ? true : false
}
end
end
end,
```
2. You are receiving a webhook that is not in JSON format.
```ruby
webhook_payload_type: "raw",
webhook_notification: lambda do |input, payload, extended_input_schema, extended_output_schema, headers, params, connection, webhook_subscribe_output|
payload.from_xml
end,
```
* * *
## [#](<#webhook-subscribe>) `webhook_subscribe`
Attribute | Description
---|---
Key | `webhook_subscribe`
Type | lambda function
Required | True if trigger is a dynamic webhook trigger. False otherwise. Should not be used when `webhook_key` is defined.
Description | This lambda function is used by dynamic webhook triggers to programmatically subscribe to webhooks. This function is invoked when a user starts the recipe using the trigger with this defined. See our [Dynamic webhook guide for more details.](</developing-connectors/sdk/guides/building-triggers/dynamic-webhook.html>)
Possible Arguments | `webhook_url` \- String representing the **recipe-specific webhook URL**. This should be passed on to the API when creating the webhook subscription.
`connection` \- Hash representing user given inputs defined in `connection`.
`input` \- Hash representing user given inputs defined in `input_fields`
`recipe_id` \- Int representing the ID of the recipe in Workato.
Expected Output | There are two possible outputs:
\- A hash which is passed on as `webhook_subscribe_output` to `webhook_unsubscribe`, `webhook_notification` and `webhook_refresh` lambda functions.
\- An array where the first index is the same hash passed on as `webhook_subscribe_output` and the second index is the webhook expiration datetime which will trigger `webhook_refresh`.
Dealing with webhook subscriptions that expire
Certain APIs like [Microsoft's Graph API (opens new window)](<https://docs.microsoft.com/en-us/graph/api/subscription-post-subscriptions?view=graph-rest-1.0&tabs=http>) allow you to create webhook subscriptions but they expire after a certain amount of time. This means your triggers need to be able to intelligently know when the webhook subscription is about to expire and refresh this subscription so you continue to receive events.
Sample code where webhook expires after 1 hour.
```ruby
webhook_subscribe: lambda do |webhook_url, connection, input, recipe_id|
[
post("https://www.acme.com/api/webhook_subscriptions", url: webhook_url),
1.hour.from_now
]
end,
webhook_refresh: lambda do |webhook_subscribe_output|
[
patch("https://www.acme.com/api/webhook_subscriptions/#{webhook_subscribe_output['id']}", refresh: true),
1.hour.from_now
]
end,
webhook_unsubscribe: lambda do |webhook_subscribe_output, connection|
delete("https://www.acme.com/api/webhook_subscriptions/#{webhook_subscribe_output['id']}")
end,
```
In the example above, the output of `webhook_subscribe` is an array that contains a datetime value that corresponds to the next time `webhook_refresh` is invoked to refresh the webhook subscription. This is similarly done for `webhook_refresh` as well. Take note that the output of `webhook_refresh` replaces the original `webhook_subscribe_output` as well.
* * *
## [#](<#webhook-refresh>) `webhook_refresh`
Attribute | Description
---|---
Key | `webhook_refresh`
Type | lambda function
Required | False. Only applicable when `webhook_subscribe` is defined.
Description | This lambda function is invoked when your webhook subscription is set to have an expiry time, defined in the output of `webhook_subscribe`. It allows you to refresh as webhook subscriptions so your trigger can continue to receive events.
Possible Arguments | `webhook_subscribe_output` \- Hash representing the output of the `webhook_subscribe` lambda function.
Expected Output | \- An array where the first index is the same hash passed on as `webhook_subscribe_output` and the second index is the webhook expiration datetime which will trigger `webhook_refresh`.
* * *
## [#](<#webhook-unsubscribe>) `webhook_unsubscribe`
Attribute | Description
---|---
Key | `webhook_unsubscribe`
Type | lambda function
Required | True if trigger is a dynamic webhook trigger. False otherwise. Should not be used when `webhook_key` is defined.
Description | This lambda function is used by dynamic webhook triggers to programmatically teardown webhooks subscriptions. This function is invoked when a user stops the recipe using the trigger with this defined. See our [Dynamic webhook guide for more details.](</developing-connectors/sdk/guides/building-triggers/dynamic-webhook.html>)
Possible Arguments | `webhook_subscribe_output` \- Hash representing the output of the `webhook_subscribe` lambda function.
`connection` \- Hash representing user given inputs defined in `connection`.
Expected Output | No output necessary.
* * *
## [#](<#webhook-notification>) `webhook_notification`
Attribute | Description
---|---
Key | `webhook_notification`
Type | lambda function
Required | True if trigger is either a dynamic webhook trigger or a static webhook trigger.
Description | This lambda function handles what this trigger should do with a webhook sent to it. You may use this function to do any data manipulation. This lambda function does not allow you to make additional HTTP requests or invoke additional reusable `methods`.
Possible Arguments | `input` \- Hash representing user given inputs defined in `input_fields`
`payload` \- Hash representing the incoming webhook's payload.
`extended_input_schema` \- See below for examples.
`extended_output_schema` \- See below for examples
`headers` \- Hash representing the incoming webhook's headers.
`params` \- Hash representing the incoming webhook's query parameters.
`connection` \- Hash representing user given inputs defined in `connection`.
`webhook_subscribe_output` \- Hash representing the output of the `webhook_subscribe` lambda function.
Expected Output | Hash which represents the output of a single job or an array of hashes which represent individual jobs.
Note
The webhook_notification lambda does not allow users to call `methods` or HTTP methods. If webhook payloads are skinny, please add actions that can take the output of the trigger to perform additional HTTP requests.
Webhook Validations
* Workato performs validations on JSON based webhooks - denoted by the webhook's `Content-Type` header, to ensure that the payload is valid JSON. Otherwise, Workato responds with 400 bad request.
* Incoming webhook payloads are expected to be UTF-8 compatible and Workato responds with 400 bad request if UTF-8 incompatible characters are found.
* * *
## [#](<#poll>) `poll`
Attribute | Description
---|---
Key | `poll`
Type | lambda function
Required | True if trigger is a [polling trigger](</developing-connectors/sdk/guides/building-triggers/poll.html>) or [Hybrid triggers](</developing-connectors/sdk/guides/building-triggers/hybrid-triggers.html>)
Description | This lambda function handles the how this trigger retrieves new records from an API to create jobs. This function is invoked every poll interval (5 mins by default but configurable on a recipe level).
Possible Arguments | `connection` \- Hash representing user given inputs defined in `connection`.
`input` \- Hash representing user given inputs defined in `input_fields`
`closure` \- Hash representing the cursor values passed to the `poll` lambda function from the previous execution of this same function.
`extended_input_schema` \- See below for examples.
`extended_output_schema` \- See below for examples
Expected Output | Hash which contains 3 attributes
\- Array of records to be turned into jobs
\- Boolean flag which tells the trigger to poll again immediately instead of 5 mins later
\- Value/Hash which is stored as the closure which will be passed to the next execution of this same function.
See below for examples
TIP
Closure values can be either a simple string/integer or a hash if you need to store multiple values for your cursor.
Example - poll:
The poll block's output should be a hash in the following structure:
```ruby
poll: lambda do |connection, input, closure, _eis, _eos|
# Timestamp which we need to filter records based off.
updated_since = (closure || input['since']).to_time.utc.iso8601
request_page_size = 100
records = get("/records/endpoint").
params(
# filter for records only updated after this time
updated_since: updated_since,
page_size: request_page_size
)
# Example JSON response
# {
# data: [
# {
# "id": "abcd123",
# "name": "record1"
# ...
# },
# {
# "id": "dcba321",
# "name": "record2",
# ...
# },
# ...
# ],
# total_records: 1000
# }
# Derive last updated since timestamp to filter
next_updated_since = records['data'].last['updated_at'] unless records.blank?
{
# Event accepts an array of records. Each record is a new job.
events: records['data'],
# Closure value which is passed as closure argument in next poll
next_poll: next_updated_since,
# Boolean flag to denote whether we should wait 5 mins to poll or poll immediately.
# Poll immediately if total records is still more than page size.
can_poll_more: records['total_records'] >= request_page_size
}
end,
```
Example - poll: - extended_input_schema and extended_output_schema
Extended input and output schema is any schema from `object_definitions` that is used in your action. This information is often useful when you dynamically generate schema and you want to use it to do data pre- or post-processing. These arguments do not include config_fields.
For example, you may use extended_input_schema to know which inputs are datetimes and should be transformed to Epoch time which is accepted by the target API. In the same fashion, you may use extended_output_schema to take the response and transform Epoch variables into ISO8601 datetimes again.
```ruby
create_object: {
description: lambda do |input, picklist_label|
"Create a <span class='provider'>#{picklist_label['object'] || 'object'}</span> in " \
"<span class='provider'>Percolate</span>"
end,
config_fields: [
{
name: 'object',
control_type: 'select',
pick_list: 'object_types',
optional: false
}
],
input_fields: lambda do |object_definitions, connection, config_fields|
object = config_fields['object']
object_definitions[object].ignored('id')
end,
execute: lambda do |connection, input, extended_input_schema, extended_output_schema|
puts extended_input_schema
# [
# {
# "type": "string",
# "name": "status",
# "control_type": "select",
# "label": "Status",
# "hint": "Status is required for creating Content",
# "pick_list": "post_statuses",
# "optional": false
# },
# ...
# ]
puts extended_output_schema
# [
# {
# "type": "string",
# "name": "id",
# "control_type": "text",
# "label": "Content ID",
# "hint": "The Content ID, Example: <b>post:45565410</b>.",
# "optional": true
# },
# {
# "type": "string",
# "name": "status",
# "control_type": "select",
# "label": "Status",
# "hint": "Status is required for creating Content",
# "pick_list": "post_statuses",
# "optional": false
# },
# ...
# ]
end,
output_fields: lambda do |object_definitions, connection, config_fields|
object = config_fields['object']
object_definitions[object]
end,
}
```
* * *
## [#](<#dedup>) `dedup`
Attribute | Description
---|---
Key | `dedup`
Type | lambda function
Required | True.
Description | This lambda function allows you to deduplicate trigger events so you don't trigger off the same events twice. This is done by forming a unique signature string based off attributes of the incoming record.
Possible Arguments | `record` \- Hash representing a single record. This is a single index in the `events` array of a `poll` lambda function or the Hash output of the `webhook_notification` lambda function. .
Expected Output | String - "#{record['id']}@#{record['created_at']}" or "#{record['id']}@#{record['updated_at']}"
* * *
## [#](<#output-fields>) `output_fields`
Attribute | Description
---|---
Key | `output_fields`
Type | lambda function
Required | True
Description | This lambda function allows you to define what output fields (datapills) should be shown to a user configuring this trigger in the recipe editor. The output of this lambda function should be an array of hashes, where each hash in this array corresponds to a separate output field (datapill). To know more about how to define input fields in Workato, click [here.](</developing-connectors/sdk/sdk-reference/schema.html>)
Possible Arguments | `object_definitions` \- Allows you to reference an object definitions. Object definitions are stores of these arrays which can represent either input and output fields. These can be referenced by any action or trigger.
`connection` \- Hash representing user given inputs defined in `connection`.
`config_fields` \- Hash representing user given inputs defined in `config_fields`, if applicable.
Expected Output | Array of hashes. Each hash in this array corresponds to a separate input field.
UI reference | 
* * *
## [#](<#sample-output>) `sample_output`
Attribute | Description
---|---
Key | `sample_output`
Type | lambda function
Required | False.
Description | This lambda function allows you to define a sample output that is displayed next to your output fields (datapills).
Possible Arguments | `connection` \- Hash representing user given inputs defined in `connection`.
`input` \- Hash representing user given inputs defined in `input_fields`
Expected Output | Hash. This hash should be a stubbed output of the `execute` lambda function.
UI reference | 
* * *
## [#](<#summarize-input>) `summarize_input`
Attribute | Description
---|---
Key | `summarize_input`
Type | Array
Required | False.
Description | Use this to summarize your input which contain long lists. Summarizing your input is important to keep the jobs page lightweight so it can load quickly. In general, when your input has lists that are longer than 100 lines, they should be summarized.
Expected Output | Array. For example, `['leads']` or `['report.records', 'report.description']`
* * *
## [#](<#summarize-output>) `summarize_output`
Attribute | Description
---|---
Key | `summarize_output`
Type | Array
Required | False.
Description | Use this to summarize your actions output which contain long lists. Summarizing your output is important to keep the jobs page lightweight so it can load quickly. In general, when your output has lists that are longer than 100 lines, they should be summarized.
Expected Output | Array. For example, `['leads']` or `['report.records', 'report.description']`
UI reference | 
Example - Summarizing inputs and outputs in job data
When working with large arrays or data, Workato tries to show all the data in the input and output tabs of the job for each action. Sometimes, this can get confusing when we are working with a large numbers of records or large strings. You can use the `summarize_input` and `summarize_output` keys to summarize the data in your job input and output tabs to make it more human readable for users of your connector.
```ruby
input_fields: lambda do
[
{
name: 'report',
type: 'object',
properties: [
{
name: 'records',
type: :array,
of: :object,
properties: [
{
name: 'item_name',
type: 'string'
}
]
},
{
name: 'description',
type: 'string'
},
{
name: 'comment',
type: 'string'
}
],
}
]
end,
summarize_input: ['report.records', 'report.description'],
```
```
### references/sdk-reference__connection.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/connection.html
> **Fetched**: 2026-01-18T02:50:25.602062
---
# [#](<#sdk-reference-connection>) SDK Reference - `connection`
This section enumerates all the possible keys available when defining your connection.
Quick Overview
To put it simply, the `connection` hash contains all the instructions your connector needs to establish a successful connection.
* The `fields` key tells your connector what input fields to show so it can collect information for authorization.
* The `extended_fields` key allows you to dynamically show more connection fields based on previous inputs. This field is optional to define.
* The `authorization` key tells your connector what to do with the information it has collected - use that to exchange it for an access_token.
* The `base_uri`key tells your connector what to prepend to every HTTP request after connection is successful. This allows you to use relative paths in your connector code when defining actions and triggers.
## [#](<#structure>) Structure
```ruby
connection: {
fields: Array,
extended_fields: lambda do |connection|
Array
end,
authorization: Hash,
base_uri: lambda do |connection|
String
end
}
```
* * *
## [#](<#fields>) fields
The 'fields' key has the following attributes:
Key
`fields`
Type
Array
Required
False
Description
Accepts an array of hashes. Each hash in this array corresponds to a separate input field.
To learn how to define input fields in Workato, see [SDK Reference - Schema](</developing-connectors/sdk/sdk-reference/schema.html>).
### [#](<#picklists-in-connection-fields>) Picklists in connection fields
For fields with `control_type` defined as `select` or `multiselect`, use the `options` attribute to define a static picklist instead of the `pick_list` attribute.
Picklist does not apply to connection hash
References to any picklists you defined in your connector are not accessible in the `connection` hash because no credentials have been received at this time.
### [#](<#example-connection-fields-with-picklist-nested-in-advanced-settings>) Example: Connection fields with picklist nested in advanced settings

```ruby
fields: [
{
name: 'api_key',
control_type: 'password',
hint: 'You can find your API key final change3' \
"under 'Settings'=>'Configure Chargebee'=>'API Keys and Webhooks'" \
" in Chargebee's web console.",
label: 'Your API Key',
default: "helloaaaabbb",
optional: false
},
{
name: 'domain',
control_type: 'subdomain',
url: 'chargebee.com'
},
{
name: "advanced_settings",
type: "object",
optional: "true",
properties: [
{
name: "environment",
optional: true,
control_type: "select",
options: [
["Development", "dev"],
["Production", "prod"]
]
}
]
}
],
```
* * *
## [#](<#extended-fields>) extended_fields
The 'extended_fields' key has the following attributes:
Key
`extended_fields`
Type
lambda function
Required
False
Description
Allows you to optionally display more input fields based on your connection. The output is expected to be a valid Workato schema. Find out more about [SDK Reference - Schema](</developing-connectors/sdk/sdk-reference/schema.html>).
### [#](<#how-to-use-extended-fields>) How to use extended_fields
With `extended_fields`, you can dynamically display additional fields based on previous input fields. If your connection setup is complex and consists of many input fields, consider limiting the number of fields that a user can see. Instead of displaying all fields at the same time, use `extended_fields` to control how many fields to display to the user initially, and when to display additional fields.
In this case, `extended_fields` provides you with the added benefit of controlling which fields to display for the users during connection setup, and guiding them through the experience. In some cases, you may also restrict some fields from the display when they are not relevant.
### [#](<#example-connection-fields-with-extended-fields>) Example: Connection fields with extended_fields
```ruby
fields: [
{
name: "api_key",
control_type: "password",
hint: "You can find your API key " \
"under 'Settings'=>'Configure Chargebee'=>'API Keys and Webhooks'" \
" in Chargebee's web console.",
label: "Your API Key"
},
{
name: "custom_domain",
label: "Are you using a custom domain?",
extends_schema: true,
control_type: "checkbox"
}
],
extended_fields: lambda do |connection|
if connection['custom_domain'] == "true"
[
{
name: "domain",
control_type: "subdomain",
extends_schema: true,
url: ".acme.com"
}
]
end
end,
```
Workato passes the connection hash to all other lambdas, including `authorization` and `execute`. The connection hash contains values from both `fields` and `extended_fields`.
### [#](<#example-connection-fields-with-extended-fields-and-extends-schema>) Example: Connection fields with extended_fields and extends_schema
The following example shows how to use `extends_schema` within `extended_fields` to create a connection setup that has multiple steps.
```ruby
connection: {
fields: [
{
name: "api_key",
control_type: "password",
hint: "You can find your API key " \
"under 'Settings'=>'Configure Chargebee'=>'API Keys and Webhooks'" \
" in Chargebee's web console.",
label: "Your API Key"
},
{
name: "custom_domain",
label: "Are you using a custom domain?",
extends_schema: true,
control_type: "checkbox"
}
],
extended_fields: lambda do |connection|
[
(
if connection['custom_domain'] == "true"
{
name: "domain",
control_type: "subdomain",
optional: false,
url: ".acme.com"
}
end
),
(
if connection['custom_domain'] == "true"
{
name: "instance_type",
control_type: "select",
extends_schema: true,
optional: false,
options: [ ["Production", "production"], ["Sandbox", "sandbox"]]
}
end
),
(
if connection['instance_type'] == "sandbox"
{
name: "protocol",
control_type: "select",
optional: false,
options: [ ["HTTPS", "https://"], ["HTTP", "http://"]]
}
end
)
].compact
end,
authorization: {
type: 'basic',
apply: lambda { |connection, access_token|
headers("x-api-key": "#{connection['api_key']}")
}
},
base_uri: lambda do |connection|
if connection['custom_domain'] == "true"
"#{connection['protocol']}#{connection['domain']}.acme.com/"
else
"https://api.acme.com/"
end
end
},
```
* * *
## [#](<#authorization>) authorization
The 'authorization' key has the following attributes:
Key
`authorization`
Type
Hash
Required
True
Description
Accepts an object with child keys corresponding to different types of authentication
Find out more about the `authorization` hash in [SDK Reference - authorization](</developing-connectors/sdk/sdk-reference/connection/authorization.html>).
* * *
## [#](<#base-uri>) base_uri
The 'base_uri' key has the following attributes:
Key
`base_uri`
Type
lambda function
Required
False. However, we recommend it.
Description
Defines the base URI for all future HTTP requests.
Possible Arguments
connection
Hash that represents user-provided inputs defined in `Connection`.
Expected Output
`String`, such as one of:
* `"https://#{connection['host']}.com/"`
* `"https://api.acme.com"`
### [#](<#configuring-your-base-uri>) Configuring your base_uri
When you define your `base_uri` key, make sure to note the final URI that you provide. There are two scenarios when using `base_uri` in conjunction with any downstream HTTP requests.
1. When you have a preceding "/" (forward slash) in the verb method (such as `get('/hello/there')`), we ignore any path parameters in the `base_uri`.
For example, `https://api.hubapi.com/test/` defined as your `base_uri` effectively becomes `https://api.hubapi.com`. The request is sent to `https://api.hubapi.com/hello/there`.
2. If you **don’t** have a preceding "/" (forward slash) in the verb method (such as `get('hello/there')`), we adopt the path parameters in your `base_uri`.
For example, `https://api.hubapi.com/test/` defined as your `base_uri` remains `https://api.hubapi.com/test/`. The request is sent to `https://api.hubapi.com/test/hello/there`.
```
### references/sdk-reference__connection__authorization.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/connection/authorization.html
> **Fetched**: 2026-01-18T02:50:26.841100
---
# [#](<#sdk-reference-authorization>) SDK Reference - `authorization`
This section enumerates all possible keys in the `authorization` hash. Some keys apply only to specific types of authentication. Immediately after the user clicks "Connect", Workato runs the code in the `authorization` hash.
The `authorization` hash contains all instructions for your connector to retrieve and use authorization parameters. This may be simple: where to place an API key in future requests. It could also be much more complex: running a series of HTTP requests to retrieve an access token.
## [#](<#structure>) Structure
```ruby
authorization: {
type: String,
client_id: lambda do |connection|
String
end,
client_secret: lambda do |connection|
String
end,
authorization_url: lambda do |connection|
String
end,
token_url: lambda do |connection|
String
end,
acquire: lambda do |connection, auth_code, redirect_uri, verifier|
Hash or Array
end,
apply: lambda do |connection, access_token|
# see apply documentation for more information
end,
refresh_on: Array,
detect_on: Array,
refresh: lambda do |connection, refresh_token|
Hash or Array
end,
identity: lambda do |connection|
String
end,
pkce: lambda do |verifier, challenge|
Hash
end,
selected: lambda do |connection|
String
end,
options: Hash,
noopener: Boolean
}
```
* * *
## [#](<#type>) `type`
Attribute | Description
---|---
Key | `type`
Type | String
Required | True
Description | Denotes the type of authentication used for this connector.
Expected Output | **One of the following:**
"basic_auth" - Used for Basic authentication.
"api_key" - Used for API key authentication.
"oauth2" - Used only for OAuth 2.0 **Auth Code Grant flows**. For other OAuth variations, use "custom_auth".
"custom_auth" - Free form authentication. Use this for multi-step, JWT, or non-standard Auth methods.
"multi" - Allows you to define multiple authentication methods at once
* * *
## [#](<#client-id>) `client_id`
Attribute | Description
---|---
Key | `client_id`
Type | lambda function
Required | True if `type` is "oauth2". Ignored otherwise
Description | Defines the client_id to use in Authorization URL and Token URL requests
Possible Arguments | `connection` \- Hash representing user given inputs defined in `Connection`
Expected Output | `String` i.e. `#{connection['client_id']}`
* * *
## [#](<#client-secret>) `client_secret`
Attribute | Description
---|---
Key | `client_secret`
Type | lambda function
Required | True if `type` is "oauth2" and `acquire` is not defined. Ignored otherwise
Description | Defines the client_secret to use in Token URL requests
Possible Arguments | `connection` \- Hash representing user given inputs defined in `Connection`
Expected Output | `String` i.e. `#{connection['client_secret']}`
* * *
## [#](<#authorization-url>) `authorization_url`
Attribute | Description
---|---
Key | `authorization_url`
Type | lambda function
Required | True if the `type` is "oauth2"; ignored otherwise.
Description | Denotes the authorization URL that users should be sent to in OAuth 2.0 Auth code grant flow.
Possible Arguments | `connection` \- Hash representing user-given inputs defined in `Connection`.
Expected Output | `String`
Example: `"https://podio.com/oauth/authorize"`
or `"#{connection['domain']}/oauth/authorize"`
Workato automatically appends these standard OAuth 2.0 parameters for the authorization URL:
state
The state to protect against CSRF attacks. Don’t configure this, as Workato uses the state to route the callback request properly.
redirect_uri
Set to `https://www.workato.com/oauth/callback`; does not have to be configured.
Configure the following query parameter manually:
response_type
This query parameter must be set to `code`.
Example:
```ruby
authorization_url: lambda do |connection| "<https://acme.com/api/oauth/authorization?response_type=code>[ (opens new window)](<https://acme.com/api/oauth/authorization?response_type=code>)"
end,
```
You may chose to include scope in your Authorization URLs.
* * *
## [#](<#token-url>) `token_url`
Attribute | Description
---|---
Key | `token_url`
Type | lambda function
Required | True if `type` is "oauth2" and `acquire` is not defined. Ignored otherwise.
Description | Denotes the token URL that used to receive an access_token
Possible Arguments | `connection` \- Hash representing user given inputs defined in `Connection`
Expected Output | `String`
i.e. `"https://podio.com/oauth/token"`
or `"#{connection['domain']}/oauth/token"`
Workato automatically appends the following standard OAuth 2.0 parameters for the token URL:
grant_type
Always set to `authorization_code`
code
The authorization code received from authorization url callback
redirect_uri
Set to `https://www.workato.com/oauth/callback` and does not have to be configured
client_id
Inferred from the `client_id` lambda, if present.
client_secret
This is inferred from the `client_secret`lambda, if present.
* * *
## [#](<#acquire>) `acquire`
Attribute | Description
---|---
Key | `acquire`
Type | lambda function
Required | True if `type` is "custom_auth".
Optional if `type` is "oauth2"
Ignored otherwise
Description | If `type` is "custom_auth", the `acquire` lambda function is only run if `refresh_on` or `detect_on` is triggered.
If `type` is "oauth2", the `acquire` lambda function is run after we receive the callback from the authorization_url.
Possible Arguments | `connection` \- Hash representing user given inputs defined in `Connection`
`auth_code` \- Only applicable if `type` is "oauth2". String representing the auth_code received from Authorization URL callback.
`redirect_uri` \- Provides the appropriate redirect URI based on the Workato DC you are in. e.g. US DC would be `https://www.workato.com/oauth/callback`.
`verifier` \- Used only in PKCE authentication, whereby you will have access to the verifier defined in the `pkce` lambda.
Expected Output | **Variable - see examples below.**
Example - acquire: - type: "oauth2"
If you specify `type` as "oauth2", the `acquire` block expects the output as an array of hashes. The array must contain the following values, in sequence:
Tokens
Tokens must be in a hash with exact key names: `access_token`, `refresh_token` and `refresh_token_expires_in`.
Owner ID
This is an optional value used for clobber detection; if not used, substitute with nil.
Other values
If the API returns tokens with other keys, such as `id_access` and `id_refresh`, you can map them here. Supply an optional hash that can be merged with the original `connection` hash.
```ruby
acquire: lambda do |connection, auth_code|
response = post("https://login.mypurecloud.com/oauth/token").
payload(
grant_type: "authorization_code",
code: auth_code,
redirect_uri: "https://www.workato.com/oauth/callback"
)
[
{ # This hash is for your tokens
access_token: response["access_token"],
refresh_token: response["refresh_token"],
refresh_token_expires_in: response["refresh_token_expires_in"]
},
# This hash is for your Owner ID. It is optional
nil,
# This is for any other value you want to append to your connection object which you can reference later on.
{ instance_id: nil }
]
end,
```
The key `refresh_token_expires_in` which denotes the seconds from now that the refresh token will expire. Since Workato only knows to refresh connections when there are jobs, there are cases where short lived refresh tokens may be expired for recipes where jobs come infrequently. For example, if the refresh token expires in 1 week and the recipe is only run once every 2 weeks, both the connection's access and refresh tokens would have expired by the time the recipe is run.
If the key `refresh_token_expires_in` is supplied, Workato will refresh the connection automatically without the need for any jobs, preserving the connection for as long as needed. There is no need to add a buffer to this time as Workato already adds a buffer to this time. For example, if the `refresh_token_expires_in` is 100 seconds, we would refresh the connection at the 85 second mark.
In some cases, APIs may not respond with expiration times for the refresh token or may respond in actual timestamps. You may also artificially create the `refresh_token_expires_in` value if you know the validity of the refresh token.
```ruby
acquire: lambda do |connection, auth_code|
response = post("https://login.mypurecloud.com/oauth/token").
payload(
grant_type: "authorization_code",
code: auth_code,
redirect_uri: "https://www.workato.com/oauth/callback"
)
[
{ # This hash is for your tokens
access_token: response["access_token"],
refresh_token: response["refresh_token"],
refresh_token_expires_in: 604800 # Value in seconds. You can provide the value manually as well.
},
# This hash is for your Owner ID. It is optional
nil,
# This is for any other value you want to append to your connection object which you can reference later on.
{ instance_id: nil }
]
end,
```
Example - acquire: - type: "custom_auth"
If you specify `type` as "custom_auth", the `acquire` lambda function expects the output as a single hash. Workato then merges the output into the original `connection` hash.
```ruby
authorization: {
acquire: lambda do |connection|
{
authtoken: get('https://accounts.zoho.com/apiauthtoken/nb/create')
}
end,
refresh_on: 401
```
Original `connection` hash:
```ruby
{
"email": "[[email protected]](</cdn-cgi/l/email-protection>)", # Given by User
"password": "pinkfloyd" # Given by User
}
```
When the user clicks the "Connect" button, Workato invokes the `test` lambda with the `connection` hash. If the `test` lambda fails with error code `401` (for example), Workato runs the `acquire` block.
After running the `acquire` block, the `connection` hash looks like this:
```ruby
{
"email": "[[email protected]](</cdn-cgi/l/email-protection>)", # Given by User
"password": "pinkfloyd" # Given by User
"authtoken": "SAMPLE_TOKEN"
}
```
Workato then attempts to invoke the `test` lambda again, with the new `connection` hash. If the `test` lambda succeeds, the connection appears as `Successful`.
Workato runs `acquire` only when the system triggers `refresh_on`, because `connection` hashes may have valid tokens. Examples:
* When the user disconnects from a valid connection that has an `authtoken` value
* When the user clicks **Connect** , and Workato attempts to use this `authtoken` instead of using a new one
* * *
## [#](<#apply>) `apply`
Attribute | Description
---|---
Key | `apply`
Type | lambda function
Required | True
Description | Defines the authentication parameters Workato adds to subsequent HTTP requests in the connector.
Possible arguments |
* `connection` \- Hash representing user given inputs defined in `Connection`.
* `access_token` \- Only applicable if `type` is "oauth2". Represents the `access_token` received from Token URL or `acquire` block.
Example - apply
The `apply` block's lambda function can output multiple commands to attach authorization parameters to all requests. The following example illustrates common methods:
```ruby
apply: lambda do |connection|
# Adds in URL parameters passed as a hash object
# i.e. authtoken=[connection['authtoken']]
params(authtoken: connection['authtoken'])
#Adds in payload fields (PATCH, POST, PUT only) passed as hash
payload(grant_type: "authorization_code",
client_id: connection["client_id"],
client_secret: connection["client_secret"],
code: auth_code)
# Adds in headers into every request passed as a hash.
# The variable access_token can be retrieved from input prompts defined in the 'fields' schema earlier or a return from the acquire block
# i.e. Authorization : Bearer [given access token]
headers("Authorization": "Bearer #{connection["access_token"]}")
# Used in conjunction with password function
# i.e. sends the input as username and password in HTTP authentication
user(connection["username"])
password(connection["username"])
end
```
ACCESS AND MODIFY THE PAYLOAD OF A CURRENT REQUEST
You can use the `apply` method to access and modify the payload of a current request. This is useful when you plan to update an existing payload or copy information into the header.
The following example demonstrates how to add a `user_id` from the connection to the payload before the final request is sent:
```ruby
apply: lambda do |connection|
if connection['user_id'].present? # Check if user_id exists in the connection
params = {}
payload do |current_payload| # Access the current payload
params = current_payload.dig('params') # Extract the params hash
end
params['user'] = connection['user_id'] # Insert user_id from the connection
payload({ "params": params }) # Merge the updated params into the payload
end
end
```
Here are special variables that you can call in the `apply` lambda function:
`current_url`
Enables matches on the current URL, and applies proper authentication.
```ruby
apply: lambda do |_connection, access_token|
if current_url.include?('<https://developer.api.autodesk.com/cost/>[ (opens new window)](<https://developer.api.autodesk.com/cost/>)')
headers('Authorization': "Bearer #{access_token}", 'Content-Type' => 'application/json')
else
headers('Authorization': "Bearer #{access_token}", 'Content-Type' => 'application/vnd.api+json')
end
end
```
`current_verb`
Enables matches on the current HTTP verb, and applies proper authentication.
```ruby
apply: lambda do |_connection, access_token|
if current_verb.include?('GET')
headers('Authorization': "Bearer #{access_token}", 'Content-Type' => 'application/json')
else
headers('Authorization': "Bearer #{access_token}", 'Content-Type' => 'application/vnd.api+json')
end
end
```
* * *
## [#](<#refresh-on>) `refresh_on`
This is an optional array of signals that identify when the system must re-acquire credentials. When it receives an error response (400, 401, 500...), the SDK framework checks the list of signals. If it finds a match, it triggers a re-authorization by running either the `refresh` lambda function for `type: oauth2` connections, or the `acquire` block for `type: custom_auth` connections.
Attribute | Description
---|---
Key | `refresh_on`
Type | Array
Required | False. If not defined, will default to one attempt at re-acquiring credentials for all errors.
Description | Tells Workato when to refresh authentication credentials. This accepts an array of integers which are matched to HTTP response codes or Regex expressions which are matched on the response body.
Expected Output | Array of ints or strings - `[ 401, /Unauthorized/ ]`
Example - `refresh_on`:
This example demonstrates the multiple approaches for defining what "signals" to watch.
401
The response status code
"Unauthorized"
The exact string that matches the whole body or title of the response
/Unauthorized/
The regex expression that matches the body or title of the response
```ruby
refresh_on: [
401,
'Unauthorized',
/Unauthorized/,
/Invalid Ticket Id/
]
```
* * *
## [#](<#detect-on>) `detect_on`
Some APIs don't signal errors with explicit response status code, such as `401`. Instead, they return a `200` (pseudo- successful response) with a payload that signals the error.
For such APIs, Workato does not pick up an error (expired credentials, bad requests, and so on); it interprets it as a successful request because of the `200`response code. However, a match with signals raises an error. When it finds a match, two things can happen:
1. There can also be a match with `refresh_on` signals. This triggers a re-authorization where the `acquire` block runs instead of the system raising an error. Then, `detect_on` matches errors that hide behind the `200` response code to identify that the system must refresh the credentials.
2. If there is no match with signals that are defined in `refresh_on`, the system raises an error.
Attribute | Description
---|---
Key | `detect_on`
Type | Array
Required | False
Description | Tells Workato when to raise an error due to a signal in the response to a request. This accepts an array of integers which are matched to HTTP response codes or Regex expressions which are matched on the response body.
Expected Output | Array of ints or strings - `[ 401, /Unauthorized/ ]`
Example - detect_on
This example demonstrates multiple approaches for defining "signals" to watch in `detect_on`.
"sample error message"
The exact string that matches the whole body or title of the response
/^\\{"response":\\{"error".+$/
Regex expression that matches the body or title of the response
```ruby
detect_on: [
"sample error message",
/^\{"response":\{"error".+$/
]
```
* * *
## [#](<#refresh>) `refresh`
This lambda applies only to `type: "oauth2"` connections.
In many situations, the API expires the access token after a prescribed amount of time. The system then uses a refresh token to obtain a new access token. Refresh tokens do not expire, usually.
Not all APIs issue refresh token credentials. Check with your provider about this requirement.
Attribute | Description
---|---
Key | `refresh`
Type | lambda function
Required | False but recommended and only valid for `type: oauth2` connections.
Description | This function will be executed if we either receive a non 2XX response in any API request, the `refresh_on` signal is triggered or if Workato knows that the refresh token is about to expire. This is used to obtain new access tokens. If this is not defined, Workato attempts to use the standard OAuth 2.0 refresh mechanism where possible or reruns the `acquire` lambda function.
Possible Arguments | `connection` \- Hash representing user given inputs defined in `Connection`
`refresh_token` \- Represents the `refresh_token` received from Token URL or `acquire` block.
Expected Output | A hash that contains a new access token. Optionally this hash can include a new refresh token (which will override the original refresh token) and a time delay before Workato refreshes the access token and refresh token. See the example below.
Example - refresh
If you specify `type:` as "oauth2", the `refresh` block expects the output as a hash. This hash must include the keys for `access_token`, and potentially for `refresh_token` if the system creates a new refresh token each time.
It is also recommended you include the key `refresh_token_expires_in` which denotes the seconds from now that the refresh token will expire. Since Workato only knows to refresh connections when there are jobs, there are cases where short lived refresh tokens may be expired for recipes where jobs come infrequently. For example, if the refresh token expires in 1 week and the recipe is only run once every 2 weeks, both the connection's access and refresh tokens would have expired by the time the recipe is run.
If the key `refresh_token_expires_in` is supplied, Workato will refresh the connection automatically without the need for any jobs, preserving the connection for as long as needed. There is no need to add a buffer to this time as Workato already adds a buffer to this time. For example, if the `refresh_token_expires_in` is 100 seconds, we would refresh the connection at the 85 second mark.
For example, if the response from the refresh token url is as follows:
```ruby
{
"access_token": "new_access_token",
"refresh_token": "new_refresh_token",
"refresh_token_expires_in": 604800
}
```
Then you should configure the HTTP request for the API call in the following manner:
```ruby
refresh: lambda do |connection, refresh_token|
url = "https://#{connection['custom_domain'].presence || 'go.trackvia.com'}"
response = post("#{url}/oauth/token").payload(
client_id: connection['client_id'],
client_secret: connection['client_secret'],
grant_type: 'refresh_token',
refresh_token: refresh_token
).request_format_www_form_urlencoded
end,
```
Alternatively, to return an array of hashes that override or add new values to your connection hash, implement something like this:
```ruby
refresh: lambda do |connection, refresh_token|
url = "https://#{connection['custom_domain'].presence || 'go.trackvia.com'}"
response = post("#{url}/oauth/token").payload(
client_id: connection['client_id'],
client_secret: connection['client_secret'],
grant_type: 'refresh_token',
refresh_token: refresh_token
).request_format_www_form_urlencoded
[
{ # This hash is for your tokens
access_token: response["access_token"],
refresh_token: response["refresh_token"],
refresh_token_expires_in: response["refresh_token_expires_in"]
},
{
user_key: user_key # Will be merged into connection hash
}
]
end,
```
In some cases, APIs may not respond with expiration times for the refresh token or may respond in actual timestamps. You may also artificially create the `refresh_token_expires_in` value if you know the validity of the refresh token.
```ruby
refresh: lambda do |connection, refresh_token|
url = "https://#{connection['custom_domain'].presence || 'go.trackvia.com'}"
response = post("#{url}/oauth/token").payload(
client_id: connection['client_id'],
client_secret: connection['client_secret'],
grant_type: 'refresh_token',
refresh_token: refresh_token
).request_format_www_form_urlencoded
[
{ # This hash is for your tokens
access_token: response["access_token"],
refresh_token: response["refresh_token"],
refresh_token_expires_in: 604800 # Value in seconds. You can provide the value manually as well.
},
{
user_key: user_key # Will be merged into connection hash
}
]
end,
```
* * *
## [#](<#identity>) `identity`
The `identity` lambda displays additional information about the connection. This output appears on the connection page, providing extra context about the authenticated user or connection.

Attribute | Description
---|---
Key | `identity`
Type | Lambda function
Required | False.
Description | The lambda allows you to display additional information about the connection object. You can make an HTTP request to retrieve user identity details, or reference existing values from the connection object. Refer to the [acquire lambda documentation](</developing-connectors/sdk/sdk-reference/connection/authorization.html#acquire>) for details on appending values from the acquire lambda to the connection object. You can reference these values in the `identity` lambda.
Possible arguments | `connection` \- A hash representing inputs defined in the `Connection` object.
Expected output | A string containing details about the connection (for example, "[[email protected]](</cdn-cgi/l/email-protection#96e3e5f3e4d6f3eef7fbe6faf3b8f5f9fb>)", "Refresh token expires in 86400 seconds")
Example - identity
In this example, the `identity` lambda makes an HTTP GET request to retrieve user information from a third-party API. It extracts the user’s email and displays it on the connection page. Use this when the connection object doesn't directly include the email.
```ruby
identity: lambda do |_connection|
get("https://app.asana.com/api/1.0/users/me")["data"]["email"]
end,
```
You can also use this lambda to return values from the connection object. The following example retrieves the `username` from the connection object:
```ruby
identity: lambda do |connection|
connection["username"]
end,
```
Additionally, you can customize the output of the lambda using values from the connection object to provide detailed information. The following example fetches the Company ID and displays a formatted string on the connection page:
```ruby
identity: lambda do |connection|
"Company ID: #{connection['company_id']}"
end,
```
* * *
## [#](<#pkce>) `pkce`
This lambda applies only to `type: "oauth2"` connections and is only needed when OAuth2 Authorization code grant with PKCE authentication is needed. This lambda allows you to defined the parameters for PKCE such as the code verifier, code challenge and challenge method.
Attribute | Description
---|---
Key | `pkce`
Type | lambda function
Required | False. Only needed for Auth code grant flows with PKCE
Description | This lambda allows you to set the parameters for the PKCE flow. It receives 2 arguments, `verifier` and `challenge`, where the `verifier` is an opaque string of 128 characters and the `challenge` is a url safe string that is the SHA256 of the verifier. In some cases, if you need a longer or shorter verifier, you can supply your own.
Possible Arguments | `verifier` \- Opaque string of 128 characters.
`challenge` \- SHA256 of the `verifier`
Expected Output | Hash which contains 3 attributes, `verifier`, `challenge` and `challenge_method`.
[Learn more about creating Authorization Code Grant flows with PKCE](</developing-connectors/sdk/guides/authentication/oauth/auth-code-pkce.html>).
* * *
## [#](<#selected>) `selected`
This lambda applies only to `type: "multi"` connections.
Use this lambda when defining `type: "multi"`; specify which inputs in the original inputs fields map to the correct Authentication type. Use this together with a declared `options`.
If `selected` is not defined but `type: "multi"` is defined, Workato defaults to any input with the internal name:`name: "auth_type"`
Attribute | Description
---|---
Key | `selected`
Type | lambda function
Required | False. Required for `type: "multi"` connections.
Description | Workato runs this function will be executed based on the inputs given in `fields` and should output a string that will match against a key defined in the `options` hash. Defaults to the field with `auth_type` as the internal name.
Possible Arguments | `connection` \- Hash representing user given inputs defined in `Connection`
Expected Output | A string that matches any keys defined in the `options` hash.
* * *
## [#](<#options>) `options`
This lambda applies only to `type: "multi"` connections.
This hash contains the definition of multiple authentication flows when you plan a connector that supports multiple authentication types.
Attribute | Description
---|---
Key | `options`
Type | Hash
Required | False. Required for `type: "multi"` connections.
Description | Hash that contains the definitions of the various authentication types within a "multi" authentication flow connector.
Schema for nested authentication definitions
Consider the schema with nested authentication definitions:
```ruby
options: {
[unique_option_name]: {
type: String,
fields: Array,
client_id: lambda do |connection|
String
end,
client_secret: lambda do |connection|
String
end,
authorization_url: lambda do |connection|
String
end,
token_url: lambda do |connection|
String
end,
acquire: lambda do |connection, auth_code|
Hash or Array
end,
apply: lambda do |connection, access_token|
# see apply documentation for more information
end,
refresh_on: Array,
detect_on: Array,
refresh: lambda do |connection, refresh_token|
Hash or Array
end,
},
[Another_unique_option_name]: {
...
}
}
```
Within the `options` hash, you must define two components for an authentication flow:
1. The _**key**_ that is unique to the authentication flow
2. The _**mechanics**_ of the authentication flow that is similar to an entirely new `authorization` hash.
Consider this example:
```ruby
fields: [
{
name: "auth_type",
control_type: "select",
pick_list: [["OAuth2", "stripe_oauth2"], ["API Key", "stripe_api_key"]],
default: "api_key",
extends_schema: true
}
],
authorization: {
type: "multi",
selected: lambda do |connection|
connection["auth_type"]
end,
options: {
stripe_oauth2: {
type: "oauth2",
fields: [
{ name: 'authorization_url' },
{ name: 'token_url' },
{ name: 'client_id' },
{ name: 'client_secret' },
],
authorization_url: lambda do |connection|
connection['authorization_url']
end,
token_url: lambda do
"https://api.stripe.com/accessToken"
end,
apply: lambda do |_, access_token|
headers("Authorization": "OAuth2 #{access_token}")
end,
},
stripe_api_key: {
type: "custom_auth",
fields: [
{
name: "api_key",
}
],
apply: lambda do |connection|
headers("Authorization": "Bearer" + " " + connection["api_key"])
end
}
},
},
```
Here, you we defined 2 authentication flows, `stripe_oauth2` and `stripe_api_key`. These keys can be anything as long as they match the output of the `selected` lambda. In each of the flows, you can see and define all lambdas in the hash. For the `stripe_oauth2` option, we defined the `type` of the authentication flow as `oauth2`, `authorization_url`, `token_url` and the `apply` block.
The significant difference here is that you can define an additional `fields` key inside each authentication flow. This adds more input fields that are based on the selected authentication method; Workato adds these fields automatically.
* * *
## [#](<#noopener>) `noopener`
The `noopener` attribute applies only to OAuth 2.0 connections.
It specifies the `rel="noopener"` HTML attribute. This attribute improves security by adding `rel="noopener"` to links that open in a new browser tab or window.
Attribute | Description
---|---
Key | `noopener`
Type | Boolean
Required | No. Defaults to `false`. Users can set to `true` for enhanced security.
Description | When set to `true`, the OAuth 2.0 authorization page launches with `target="blank"` and `rel="noopener"` attributes. This attribute improves security and prevents linked third-party websites from taking control of the browser tab through the window object.
```
### references/sdk-reference__schema.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/schema.html
> **Fetched**: 2026-01-18T02:50:35.280283
---
# [#](<#sdk-reference-workato-schema>) SDK Reference - Workato Schema
The following section defines how to define input and output fields in Workato - collectively called "Schema". You can apply this information anywhere in your connector code where input fields or output fields (datapills) are defined. This could be in places such as `connection`, `actions`, `triggers`, and `object_definitions`
Quick Overview
Getting the hang of Workato schema is essential for building user-friendly and intuitive connectors. You can give various attributes to your connector to make it easier to use. This schema is a simple array of hashes where each index in the array represents a single input field or output field.
These definitions are completely interchangeable for both input and output fields, making it easier to write the schema once and reuse it.
## [#](<#structure>) Structure
```ruby
[
{
name: String,
label: String,
optional: Boolean,
type: String,
hint: String,
of: String,
properties: Array,
control_type: String,
toggle_hint: String,
toggle_field: Hash,
default: String,
pick_list: String,
delimiter: String,
sticky: Boolean,
convert_input: String,
convert_output: String,
change_on_blur: Boolean,
support_pills: Boolean,
custom: Boolean,
extends_schema: Boolean,
list_mode: String,
list_mode_toggle: Boolean,
item_label: String,
add_field_label: String,
empty_schema_message: String,
sample_data_type: String,
ngIf: String
},
{
# Another field definition
}
]
```
* * *
## [#](<#attribute-description>) Attribute description
Key | Definition
---|---
name | Required. The name of this field. For example, id or created_at
optional | Optional. Default is false. Applies to input fields and ensures users provide input for this field before running the recipe.
label | Optional. All fields have default labels based on the field name. Use this to change the default value of the field label.
hint | Optional. This allows you to add some hints below the input field to guide the user. Links to documentation can be given using HTML syntax.
type | Optional. The data type of this field. Default value is "string". Possible values are:
\- "string"
\- "integer"
\- "number"
\- "date_time"
\- "date"
\- "timestamp"
\- "boolean"
\- "object" - Must be accompanied by `properties`
\- "array" - Must be accompanied by `of`
of | Optional except when `type: "array"`. Used in conjunction with Arrays to define the data type of the Array. Possible values are:
\- "string"
\- "integer"
\- "number"
\- "date_time"
\- "date"
\- "timestamp"
\- "boolean"
\- "object" - Denotes an array of objects. Must be accompanied by the `properties` attribute.
properties | Optional except when `type: "object"` or when `type: "array"` and `of: "object"`. Accepts an array of schema to denote the properties of the object.
control_type | Optional. This field relates only to input fields, and it dictates the input field type to expose in a recipe. Default is "string". When this schema is used as an output field, this attribute is ignored.
Refer to the list of [supported control types](</developing-connectors/sdk/sdk-reference/schema.html#control-types>).
toggle_hint | Optional. This represents the label of the primary toggle. See [toggle fields](<#using-toggle-fields>) for more information.
toggle_field | Optional. Hash representing the secondary toggle for this input field. See [toggle fields](<#using-toggle-fields>) for more information.
default | Optional. Allows you to set a default value for that input field.
pick_list | Optional. If control_type is :select or :multiselect, this property is required. Allows you to reference a picklist defined in the `pick_lists` key or define one directly. If defining a picklist directly, provide the same 2D array described [here](</developing-connectors/sdk/sdk-reference/picklists.html>)
options | Synonymous with pick_list and used only for `connection` input fields.
delimiter: | Optional unless `control_type: "multiselect"`. This delimiter is used between each input the user provides.
sticky | Optional. Use this property to make this field always visible as an input field. By default, inputs that are optional are hidden inside the optional fields drop-down. Use `sticky: true` so they show up beside required fields.
convert_input | Optional. When defining input fields, values passed into these fields are assumed to be strings regardless of their `type` defined. `convert_input` allows you to convert and transform these inputs even before they are passed to your `execute` block's `input` argument. [Learn more](<#using-convert-input-and-convert-output-for-easy-transformations>)
convert_output | Optional. When defining output fields, the `name` of each field is matched against the keys in the actual output of the `execute` lambda function. This does not, however, ensure that the `value` of the output matches the `type` declared for its matched field. `convert_output` allows you to convert and transform these inputs as well as correctly "cast" incoming values assigned to a specific output field. [Learn more](<#using-convert-input-and-convert-output-for-easy-transformations>)
change_on_blur | Optional. When true, config fields and dependent fields only evaluate the value when the user blurs out of the field instead of after every keystroke. This parameter often doesn't need to be configured.
support_pills | Optional. The default value is true. When false, this field doesn't allow datapills to be mapped to it. This parameter often doesn't need to be configured.
custom | Optional. When true, a special marker is introduced to indicate to the user that this field is custom. Normally used when dynamically generating object definitions which may contain custom fields.
extends_schema | Optional. Allows a field to behave like a `config_field`
list_mode | Optional. Used when `type: "array"` and `of: "object"`. Workato defaults to dynamic lists but this parameter allows you to set this input field to a static array input field. Possible values are:
\- "static" - Users must define each index in this array.
\- "dynamic" - Users can dynamically define each index in this array using list datapills.
list_mode_toggle | Optional. Used when `type: "array"` and `of: "object"`. Allows users to toggle between static and dynamic lists when working with arrays. Defaults to true. Set list_mode_toggle: false to disallow users to toggle list modes.
item_label | Optional. Only used with `control_type: "schema-designer"` or `control_type: "key_value"`. This allows you to configure the item name stated in the modal popup. Setting item_label: "Item Label" results in the following: 
add_field_label | Optional. Only used with `control_type: "schema-designer"` or `control_type: "key_value"`. This allows you to configure the label of the add button. Setting add_field_label: "Custom Add Label" results in the following: 
empty_schema_message | Optional. Only used with `control_type: "schema-designer"` or `control_type: "key_value"`. This allows you to configure the message when the input field is empty. Setting empty_schema_message: `Custom empty schema message that allows to add field and generate schema` results in the following: 
sample_data_type | Optional. Only used with `control_type: "schema-designer"`. This allows you to configure the type of data the schema-designer input field accepts. Setting `sample_data_type: csv` results in the following:  Other possible inputs are json_input and xml. The schema-designer defaults to json_input.
ngIf | Optional. Allows you to define a boolean statement. If true, this field displays. The boolean statement can reference other inputs in the same schema. For example, `ngIf: 'input.object_name != "approval"'` where the root node is `input` and you can traverse to a specific field via dot notation. Click [here](<#using-ngif-to-conditionally-hide-or-display-fields>) for more details.
tree_options | Optional. Only used when `control_type: 'tree'`. This allows you to control the behavior of the `tree` picklist. This key expects a Hash which has three possible keys - `selectable_folder`,`multi_select` and `force_selection_hierarchy`. Find out more [here](</developing-connectors/sdk/sdk-reference/picklists.html>).
## [#](<#control-types>) Control types
The `control_type` key affects how users configure the input fields you define. For each input field (index in the schema array), you can control its look by assigning one of the values to the `control_type` attribute:
Control type | Description
---|---
text | Simple text input field with a formula mode option.

text-area | Long text input field with a formula mode option.

plain-text | Simple text input field without a formula mode option.

plain-text-area | Long text input field with formula mode option. This input field can be expanded using the adjust icon.

password | Text input field specifically designed for sensitive information, such as passwords. Text input in this control type is masked.

integer | Simple number field with icon to indicate an integer value. This control type has a formula mode option.

number | Decimal number field with icon to indicate a float value. This control type has a formula mode option.

url | Text field with icon to indicate a URL value. This control type has a formula mode option.

select | Control type to provide a predefined list of values to choose from. Make sure to include the `pick_list` property.

checkbox | Simple Yes/No select interface. It is advisable to add a [toggle field](<#using-toggle-fields>) for dynamic mapping and formula mode option.

multiselect | Control type similar to `select` with additional ability to select multiple values. This control type must be accompanied with `pick_list` and `delimiter` properties.

date | Control type indicating date value. This control type has a formula mode option. 
date_time | Control type indicating date with time value. This control type has a formula mode option. 
phone | Control type indicating phone value. This control type has a formula mode option.

email | Control type indicating email value. This control type has a formula mode option.

subdomain | Control type to indicate a subdomain of a particular site. Typically used in connection fields. Make sure to include the `url` property.

schema-designer | Control type that allows you to collect schema information from users. This is useful when you need users to give your input during recipe design time to create input or output fields. This requires `extends_schema: true` to take effect.
```ruby
{
name: "schema",
extends_schema: true,
schema_neutral: false,
control_type: 'schema-designer',
label: 'Schema designer label',
hint: 'Hint for schema designer field',
item_label: 'button',
add_field_label: 'Custom Add Label',
empty_schema_message: 'Custom empty schema message that allows to <button type="button" data-action="addField">add field</button> and <button type="button" data-action="generateSchema">generate schema</button>',
sample_data_type: 'csv' # json_input / xml
},
```

key_value | Control type that allows you to collect key and value pairs from users. This is useful when you need users to give your input during recipe design time for URL query parameters. Must be accompanied with `properties` defined and two inputs given.
```ruby
{
name: "key_value",
control_type: "key_value",
label: "key_value",
empty_list_title: "Add query parameters",
empty_list_text: "Description for empty list",
item_label: "Query parameter",
type: "array",
of: "object",
properties: [
{ name: "key"},
{ name: "value"}
]
},
```

## [#](<#nested-objects>) Nested objects
Often, data returned from API request is not a simple one-level JSON. More often than not, the returned JSON object is much more complex, with multiple levels of nesting. This section aims to illustrate how to define nested fields.
#### [#](<#sample-code-snippet>) Sample code snippet
```ruby
{
"id": "00ub0oNGTSWTBKOLGLNR",
"status": "STAGED",
"created": "2013-07-02T21:36:25.344Z",
"activated": null,
"lastLogin": "2013-07-02T21:36:25.344Z",
"profile": {
"firstName": "Isaac",
"lastName": "Brock",
"email": "[[email protected]](</cdn-cgi/l/email-protection>)",
"login": "[[email protected]](</cdn-cgi/l/email-protection>)",
"mobilePhone": "555-415-1337"
},
"credentials": {
"provider": {
"type": "OKTA",
"name": "OKTA"
}
},
"_links": {
"activate": {
"href": "https://your-domain.okta.com/api/v1/users/00ub0oNGTSWTBKOLGLNR/lifecycle/activate"
}
}
}
```
Nested object field `profile` can be defined `type: :object` with fields nested inside using `properties`. Properties should be an array of fields objects (just like `fields` within the `user` object).
```ruby
object_definitions: {
user: {
fields: lambda do
[
{
name: "id"
},
{
name: "status"
},
{
name: "created",
type: :timestamp
},
{
name: "activated",
type: :timestamp
},
{
name: "lastLogin",
type: :timestamp
},
{
name: "profile",
type: :object,
properties: [
{
name: "firstName"
},
{
name: "lastName"
},
{
name: "email",
control_type: :email
},
{
name: "login",
control_type: :email
},
{
name: "mobilePhone",
control_type: :phone
}
]
}
]
end
}
}
```
## [#](<#nested-arrays>) Nested Arrays
The other common type of nested field is an array of objects. This type of field contains a list of repeated objects of the same fields. The defining such fields is similar to defining objects. Take the following sample `user` object from Asana as an example.
#### [#](<#sample-code-snippet-2>) Sample code snippet
```ruby
{
"data": {
"id": 12149914544379,
"email": "[[email protected]](</cdn-cgi/l/email-protection>)",
"name": "Ee Shan",
"workspaces": [
{
"id": 1041269201604,
"name": "Workato"
},
{
"id": 498346130780,
"name": "Product Documentation"
}
]
}
}
```
The `workspaces` array should be given `type: :array` as well as `of: :object`. This tells the `object_definitions` framework that the field contains an array of objects. Similar to nested objects, you must define `properties`, which is an array of fields corresponding to the fields of each object in the `workspaces` array.
```ruby
object_definitions: {
user: {
fields: lambda do
[
{
name: 'id',
type: :integer
},
{ name: 'name' },
{
name: 'email',
control_type: :phone
},
{
name: 'workspaces',
type: :array,
of: :object,
properties: [
{
name: 'id',
label: 'Workspace ID',
type: :integer
},
{ name: 'name' }
]
}
]
end
}
}
```
## [#](<#using-toggle-fields>) Using toggle fields
Toggle fields are a special type of input fields that allow 2 input types. They are a great way to introduce greater flexibility and increase usability in your input fields. When used, toggle fields allow users to switch between two control types.
TIP
Toggle fields are often used in conjunction with pick lists. Since pick lists produce drop-downs, users are unable to map datapills which they normally would in recipes. Toggle fields fix that by allowing them to toggle to plain text fields which can accept datapills.
#### [#](<#sample-code-snippet-3>) Sample code snippet
```ruby
input_fields: lambda do |object_definition, connection, config_fields|
{
name: "parser_id",
label: "Document Parser",
hint: "The Document Parser the file gets imported to",
control_type: :select,
pick_list: "parsers",
optional: false,
toggle_hint: "Select from list",
toggle_field: {
name: "parser_id",
label: "Parser ID",
type: :string,
control_type: "text",
optional: false,
toggle_hint: "Use Parser ID",
hint: "Go to home page and select the required parser. If the URL is 'https://app.docparser.com/stack/ynrqkdxvaghs/overview', then 'ynrqkdxvaghs' is the ID"
}
},
end
```
 _Primary toggle field_
 _Secondary toggle field_
You can use a picklist input type to create a customized user experience. However, this makes the action value mapping static. All recipe jobs executing this action use the single parser ID value you selected, because only one value can be selected from the picklist. You can avoid this limitation by using a text field. A text field allows you to dynamically map the input field value.
If both field types are preferred for your planned use case, you can use the `toggle_field` to provide both input options to users. The picklist type is set as the primary toggle and the text field is set as the secondary (nested `toggle_field`) because the most common scenario is for users to select one parser per action.
## [#](<#using-fields-with-extends-schema>) Using fields with extends_schema
In some cases, the input fields you plan to show in an action depend on the answer to an input field in the same action. The `extends_schema` feature enables you to add dynamic behavior to your actions without using configuration fields.
#### [#](<#sample-code-snippet-4>) Sample code snippet
```ruby
object_definitions:
schema_input: {
fields: lambda do |connection, config_fields, object_definitions|
input_schema = parse_json(config_fields.dig('schema') || '[]')
[
{
name: "schema",
extends_schema: true,
schema_neutral: false,
control_type: 'schema-designer',
label: 'Schema designer label',
hint: 'Hint for schema designer field',
item_label: 'button',
add_field_label: 'Custom Add Label',
empty_schema_message: 'Custom empty schema message that allows to <button type="button" data-action="addField">add field</button> and <button type="button" data-action="generateSchema">generate schema</button>',
sample_data_type: 'csv' # json_input / xml
},
if input_schema.present?
{ name: 'data', type: 'object', properties: input_schema }
end
].compact
end
}
```
The preceding code sample demonstrates how to use an input field with `control_type` set to `schema-designer`. By setting `extends_schema` to `true`, user inputs trigger a re-evaluation of the `object_definitions` block. The inputs become `config_fields` for further processing. This setup allows inputs for the `schema` field to directly influence the creation of the `data` input field.
The `schema_neutral` parameter enables you to update titles or descriptions without modifying the schema's logic. This provides increased flexibility and control when changes impact the title or description but not the schema itself. `schema_neutral` allows you to return results of an extended schema even when the input is empty.
## [#](<#arrays-of-primitive-scalar-data-types>) Arrays of primitive scalar data types
Arrays in Workato input and output schema currently only work with objects. In cases where you need to collect an array of primitive data types such as strings or integers, consider the code below. In this example, we plan to send an array of strings to a target API in the format `["column1","column2","column3"]`. This can be done by declaring an array of objects with the declaration for the `column names` input field wrapped inside the object layer.
#### [#](<#sample-code-snippet-5>) Sample code snippet
```ruby
object_definitions: {
columns: {
fields: lambda do
[
{
label: 'String Array',
name: 'array_of_strings',
type: "array",
of: "string"
}
]
end
}
}
```
## [#](<#using-ngif-to-conditionally-hide-or-display-fields>) Using ngIf to conditionally hide or display fields
Sometimes, you need to hide or display fields based on a user's input. This could be in the `input_fields` key or the `config_fields` key. For example, if you want to showcase an additional `config_field` based on a user's input to another `config_field`. Another use case would be to showcase a new input field based on a user's input for another input field. For example, if we have an action that creates a user - if one input field is `assign_new_password`, we would use `ngIf` to conditionally show `new_password` if the user gave `true` to that input.
#### [#](<#sample-code-snippet-6>) Sample code snippet
```ruby
object_definitions: {
create_user: {
fields: lambda do |_connection, config_fields|
[
{
name: 'assign_new_password',
label: 'Assign new password during creation',
hint: "Select <b>yes</b> to provide a password for this newly created user. If set to <b>no</b>, an email is sent to user to define their own password.",
control_type: 'checkbox',
type: 'boolean',
sticky: true,
},
{
name: 'password_input',
label: 'Custom password',
control_type: 'password',
ngIf: 'input.assign_new_password == "false"',
sticky: true,
hint: 'Required if <b>Assign new password during creation</b> is set to <b>yes</b>. ' \
'Provide a password of length 8 to 100 characters.'
},
]
end
}
}
```
## [#](<#using-convert-input-and-convert-output-for-easy-transformations>) Using `convert_input` and `convert_output` for easy transformations
In most cases, when users map fields to your action's input fields, these values are assumed to be of the data type `string` regardless of the actual `type` or `control_type` you have configured for the input field.
For example, the schema below:
```ruby
[
{
name: "account_id",
control_type: "integer"
type: "int"
}
]
```
When the `input` is passed to the `execute` lambda, it would still arrive in the JSON object as
```ruby
{
"account_id": "123"
}
```
In these cases, you can use `convert_input` to transform the input into its expected data type even before it's passed to the `execute` lambda.
For example:
```ruby
[
{
name: "account_id",
control_type: "integer"
type: "int",
convert_input: "integer_conversion"
}
]
```
With `convert_input` defined, the `input` argument passed to your `execute` lambda is:
```ruby
{
"account_id": 123
}
```
This allows you to configure the expected data formats when defining the schema and allows you to skip any unnecessary code in your `execute` for ensuring data is in the correct format. The same behavior is also seen in reverse when you use `convert_output`, where a value from the output of your `execute` lambda is transformed when its mapped to a output field which contains a `convert_output` attribute.
### [#](<#predefined-convert-input-values>) Predefined `convert_input` values
* `integer_conversion`
* Converts input into data type integer
* `float_conversion`
* Converts input into data type float
* `date_conversion`
* Converts input into data type date
* `render_iso8601_timestamp`
* Converts input into date string that conforms to ISO8601 standards
* `boolean_conversion`
* Converts input into data type boolean
### [#](<#predefined-convert-output-values>) Predefined `convert_output` values
* `integer_conversion`
* Converts output into data type integer/number
* `float_conversion`
* Converts output into data type float
* `date_conversion`
* Converts output into data type date
* `date_time_conversion`
* Converts output into a format that matches JavaScript's Date object's `toJSON` method
* `boolean_conversion`
* Converts output into data type boolean
TIP
Sometimes the above transformations may not suite your needs. For example, when you need transformations to a specific time format or if you want to manipulate the structure of your data. In these cases, you can create your own custom `convert_input` and `convert_output` functions. Continue reading to learn how to do this.
## [#](<#advanced-transformations-using-methods-in-convert-input-and-convert-output>) Advanced transformations using methods in `convert_input` and `convert_output`
In some situations, APIs require you to send data in a specific format. For example, an API can require date times in `epoch` time. In many cases, we cannot assume that users in the recipe editor are comfortable with `epoch` time or that the upstream systems they are mapping data from provide date times in `epoch` format. In cases like these, we would use methods in conjunction with `convert_input` to cast their inputs to the proper format.
For example:
```ruby
[
{
name: 'invoice_date',
control_type: "date_time",
convert_input: "epoch_time_conversion"
}
]
```
and a matching method named `epoch_time_conversion`:
```ruby
methods: {
epoch_time_conversion: lambda do |val|
val.to_time.to_i
end
}
```
which would render inputs such as `"2021-10-27T00:00:00-07:00"` to `1635318000`.
You can also use custom lambdas to perform custom transformations on nested structures. For example, when an API requires you to send a payload in the format:
```ruby
{
"data": {
"name": {
"value": "abc123"
},
"address": {
"value": "def456"
}
}
}
```
The corresponding input_field representation might be overly nested, making it cumbersome for users.
 _Input fields represented by the earlier example_
Custom lambdas help you improve the UX of your connector by allowing you to present a relatively flat input field structure and performing the transformations afterwards.
For example:
```ruby
[
{
name: 'data',
type: 'object',
properties: [
{
name: "name"
},
{
name: "address"
}
],
convert_input: "key_value_conversion"
}
]
```
and a matching method named `key_value_conversion`:
```ruby
methods: {
key_value_conversion: lambda do |val|
# val in this case is the entire "data" object
val.map do |key, value|
{
key => {
"value" => value
}
}
end.inject(:merge)
end
}
```
Resultant JSON:
```ruby
{
"data": {
"name": {
"value": "abc123"
},
"address": {
"value": "def456"
}
}
}
```
 _Input fields that produce the same output due to custom lambdas_
Furthermore, you can call `convert_input` and `convert_output` on schema of type `arrays`. This allows you to perform transformations on the entire array of inputs.
For example:
```ruby
[
{
name: 'products',
type: 'array',
of: 'object',
convert_input: "product_conversion",
properties: [
{
name: "name"
},
{
name: "qty"
}
]
}
]
```
and a matching method named `string_concat_conversion`:
```ruby
methods: {
product_conversion: lambda do |val|
# Render_input is called on each index of the array THEN the whole array
if val.is_a?(Array)
val
else
{
val['name'] => val['qty']
}
end
end,
}
```
The user's input would look something like this:
```ruby
{
"products": [
{
"name": "car",
"qty": "100"
},
{
"name": "wrench",
"qty": "10"
}
]
}
```
Resultant JSON:
```ruby
{
"products": [
"car": "100"
"wrench": "10"
]
}
```
```
### references/sdk-reference__object_definitions.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/object_definitions.html
> **Fetched**: 2026-01-18T02:50:31.493402
---
# [#](<#sdk-reference-object-definitions>) SDK Reference - `object_definitions`
Object definitions represent specific resources from a target application. For example, they represent the schema for Salesforce leads or Snowflake rows.
These definitions are stored as arrays of hashes, and are used in both input and output fields.
Avoid repeating code with object definitions
Store object definition in one place and reuse throughout the custom connector.
## [#](<#structure>) Structure
```ruby
object_definitions: {
[Unique_object_definition_name]: {
fields: lambda do |connection, config_fields, object_definitions|
Array
end
},
[Another_unique_object_definition_name]: {
...
}
},
```
* * *
Attribute | Description
---|---
Key | `fields`
Type | lambda function
Required | True
Description | This lambda function is invoked whenever its parent object_definition's key is called in an action or trigger. It is able to make HTTP requests to dynamically build schema from metadata endpoints. The output of this lambda function should be an array of hashes that represents the input or output fields. This is called Workato Schema. Find out more [here](</developing-connectors/sdk/sdk-reference/schema.html>)
Possible Arguments | `connection` \- Hash representing user given inputs defined in the connection.
`config_fields` \- Hash representing the user given inputs from config fields in the action or trigger that referenced this object definition.
`object_definitions` \- Allows you to reference other object_definitions.
Expected Output | Array
DEFINE ARGUMENTS FOR OBJECT DEFINITIONS
You must define arguments for your object definitions, even if they are not used. Workato determines whether your schema is static or dynamic based on whether your object definitions have arguments defined. Changing your schema from static to dynamic is considered backward incompatible; you must stop running recipes and refresh the schema for the changes to take effect.
**Static object definition**
```ruby
lead: {
fields: lambda do
[
{ name: "name", type: :boolean },
{ name: "email" },
{ name: "number"}
]
end
}
```
**Dynamic object definition**
```ruby
lead: {
fields: lambda do |connection, config_fields, object_definitions|
[
{ name: "name", type: :boolean },
{ name: "email" },
{ name: "number"}
]
end
}
```
_Workato recommends that you define all object_definitions dynamically (with arguments) to ensure no issues arise from any future changes._
Example - fields
Object_definitions can be static and simply store an array. When this object definition is referenced, the `fields` lambda function returns this array.
```ruby
object_definitions: {
lead: {
fields: lambda do |connection, config_fields, object_definitions|
[
{ name: "name", type: :boolean },
{ name: "email" },
{ name: "number"}
]
end
}
}
```
Object_definitions can also be dynamic and make HTTP requests to metadata endpoints. When this object definition is referenced, the `fields` lambda function makes this request, receives the response and should massage the response into the same array that can be returned to the `input_fields` or `output_fields` lambda function that referenced it. Find out more about defining these `input_fields` and `output_fields` (called Workato schema) [here](</developing-connectors/sdk/sdk-reference/schema.html>)
```ruby
object_definitions: {
form: {
fields: lambda do |connection|
get("https://api.unbounce.com/pages/#{connection['page_id']}/form_fields")["formFields"].
map { |field| { name: field["id"] } }
end
}
}
```
Example - Building schema from multiple object_definitions
To keep your code DRY, our recommendation is to logically break up your schema definitions into separate object_definitions. These object_definitions may be dynamically generated separately and pieced together.
```ruby
object_definitions: {
create_object_output: {
fields: lambda do |connection, config_fields, object_definitions|
if config_fields['object'] == 'customer'
[
{
name: 'customer',
type: 'object',
properties: object_definitions['customer_schema']
},
{
name: 'card',
type: 'object',
properties: object_definitions['card_schema']
}
]
elsif config_fields['object'] == 'subscription'
[
{
name: 'customer',
type: 'object',
properties: object_definitions['customer_schema']
},
{
name: 'subscription',
type: 'object',
properties: object_definitions['subscription_schema']
},
{
name: 'card',
type: 'object',
properties: object_definitions['card_schema']
}
]
end
end
}
}
```
```
### references/sdk-reference__methods.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/methods.html
> **Fetched**: 2026-01-18T02:50:30.415584
---
# [#](<#sdk-reference-methods>) SDK Reference - `methods`
Reusable methods are supported in Workato. Reusable methods help keep your custom adapter code DRY and may be used in any lambda function in your connector.
Quick Overview
Reusable methods are the same as custom functions that can be called in any portion of the code. Use them to keep your code concise and maintainable.
## [#](<#structure>) Structure
```ruby
methods: {
[Unique_method_name]: lambda do |[unique_argument_name]|
Array, Hash, String, Int, Boolean
end,
[Another_unique_method_name]: lambda do |[unique_argument_name], [another_unique_argument_name]|
Array, Hash, String, Int, Boolean
end
},
```
* * *
Attribute | Description
---|---
Key | `[Unique_method_name]`
Type | lambda function
Required | True
Description | This lambda function can be invoked anywhere in the connector code such as actions, triggers, object_definitions, or even other methods. This is done by the using the special syntax `call('unique_method_name', input)`
Possible Arguments | Arguments can be defined by you. There can be any number of arguments. Splat operators are not allowed.
Expected Output | Variable
Example - methods: - Using a reusable method
Use the `call()` method to reference a method. This method takes in two parameters:
1. The method name - You can use either "method_name" (string) or :method_name (symbol) representations.
2. Input fields - This is mapped to the arguments defined in the method definition.
Here we have the definition of a recursive method which returns the factorial of a number.
```ruby
methods: {
factorial: lambda do |input|
number = input['number']
if number > 1
number * call('factorial', { number: number - 1 })
else
number
end
end
}
```
```ruby
actions: {
factorial: {
input_fields: lambda do
[
{ name: "number", type: :integer }
]
end,
execute: lambda do |connection, input|
{ factorial: call(:factorial, { number: input['number'] }) }
end
},
```
```
### references/sdk-reference__picklists.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/picklists.html
> **Fetched**: 2026-01-18T02:50:32.686527
---
# [#](<#sdk-reference-pick-lists>) SDK Reference - `pick_lists`
Picklists are used in conjunction with some input fields to enumerate the possible options in a drop-down. Picklist options can be stored in the `pick_lists` key or defined directly in the input field hash. Input fields that use `pick_list` attribute have to be of the following `control_type`:
* `select`
* Allows the user to select a single input from the drop-down.
* `multiselect`
* Allows the user to select multiple inputs from the drop-down.
* `tree`
* Allows the user to select a single or multiple inputs from a hierarchical drop-down.
Quick Overview
Pick lists are a great way to make your connector easier to use when the API only accepts a certain set of values. Rather than having the user type it in manually, you should use picklists so they can easily select the value from a drop-down. The `pick_list` key is where you can store these options and refer to them when building your input fields.
## [#](<#structure>) Structure
```ruby
pick_lists: {
[Unique_pick_list_name]: lambda do |connection, pick_list_parameters|
Array
end,
[Another_unique_pick_list_name]: lambda do |connection, pick_list_parameters|
Array
end
},
```
* * *
Attribute | Description
---|---
Key | `[Unique_pick_list_name]`
Type | lambda function
Required | True
Description | This lambda function is invoked whenever its parent object_definition's key is called in an action or trigger. It is able to make HTTP requests to dynamically build schema from metadata endpoints. The output of this lambda function should be an array of hashes that represents the input or output fields.
Possible Arguments | `connection` \- Hash representing user given inputs defined in `connection`
`pick_list_parameters` \- Used when defining dependent picklists.
Expected Output | Array of Array
Pick_lists outputs should be a 2D array in the following format:
```ruby
[
[ "Picklist Label", "Value" ],
[ "Picklist Label", "Value" ],
[ "Picklist Label", "Value" ],
[ "Picklist Label", "Value" ]
]
```
\- pick_lists not allowed for connections fields
Example - options in connection fields
When defining enumerable values for connection fields, take note that you may not reference `pick_lists` defined in your connector.
Instead, you may define these fields statically and using the schema attribute - `options`
```ruby
connection: {
fields: [
{
name: 'environment',
label: 'Instance environment',
control_type: 'select',
options: [
['Production', 'production'],
['Sandbox', 'Sandbox']
]
}
]
}
```
Example - pick_lists: - Static
Pick_lists can be static. When referenced, this definition would return the array stored in it. When an input field references this picklist, this array is returned and rendered on the front end as a drop-down.

```ruby
input_fields: lambda do |object_definitions|
[
{
name: 'event_category',
control_type: 'select',
pick_list: 'events'
}
]
end,
```
```ruby
pick_lists: {
events: lambda do |connection|
[
["Meeting","meeting"],
["Webinar","webinar"],
["Cloud recording","recording"],
["User","user"],
]
end
},
```
Example - pick_lists: - dependent & static
Dependent pick lists allow you to change the contents of a pick list based on the value of another field. For example, rather than displaying all the cities in a single pick list, we can selectively display only cities from a country, selected in another field.

```ruby
input_fields: lambda do |_object_definitions|
[
{
name: 'country',
control_type: 'select',
pick_list: 'countries',
optional: false
},
{
name: 'city',
control_type: 'select',
pick_list: 'cities',
pick_list_params: { country: 'country' },
optional: false
}
]
end
```
```ruby
pick_lists: {
countries: lambda do |_connection|
[
['United States', 'USA'],
['India', 'IND']
]
end,
cities: lambda do |_connection, country:|
{
'USA' => [
['New York City', 'NYC'],
['San Fransisco', 'SF']
],
'IND' => [
['Bangalore', 'BNG'],
['Delhi', 'DLH']
]
}[country]
end
}
```
Example - pick_lists: - dependent & dynamic
In this example, accounts is an independent dynamic pick list while properties is a dependent dynamic pick list. When defining dynamic picklists, the response from the HTTP request should still be transformed into the same array of arrays.
In this example, we used the `.pluck` function to do the transformation.

```ruby
input_fields: lambda do |_object_definitions|
[
{
name: 'scope_id',
label: 'Team',
optional: false,
control_type: 'select',
pick_list: 'tenant_licenses'
},
{
name: 'platform_id',
control_type: 'select',
pick_list: 'platforms',
label: 'Platform',
pick_list_params: { scope_ids: 'scope_id' },
hint: 'Platform is required for creating Content'
}
]
end
```
```ruby
pick_lists: {
tenant_licenses: lambda do |connection|
app_id = get("api/v5/client/client:#{connection['client_id']}")&.
dig('data', 'app_id')
tenant_id = get("/api/v5/app/#{app_id}")&.dig('data', 'tenant_id')
get('/api/v5/license/').
params(tenant_id: tenant_id,
statuses: 'active')['data']&.
select { |lic| lic['parent_id'].present? }&.
pluck('name', 'id')
end,
platforms: lambda do |_connection, scope_ids:|
get('/api/v5/platform/').
params(scope_ids: scope_ids)['data']&.
pluck('name', 'id')
end,
}
```
Example - pick_lists: - tree
Workato also allows for `tree` type picklists. Tree picklists are often used to model hierarchical structures in applications such as file/folder structures. When using tree picklists, traditional `pick_list_parameters` are ignored and replaced by a double splat variable.
To best explain this, we will use the concept of a file and folder structure, where folders might contain additional folders or files. All folders and files are considered nodes, while the main distinction is that folders might have child nodes whereas files may not. When you define a tree picklist, each time the user clicks on a folder node, the picklist is re-evaluated to build out the child nodes within it. The value of the folder node that the user clicked on can be found by `args&.[](:__parent_id)`. If this value is nil, this indicates that we are at the root node.
```ruby
input_fields: lambda do |_object_definitions|
[
{
name: 'path',
label: 'File path',
optional: false,
control_type: 'tree',
pick_list: "file_path"
},
]
end
```
```ruby
pick_lists: {
file_path: lambda do |_connection, **args|
# Get sub folders
if (folder_path = args&.[](:__parent_id)).presence
path = []
response = get("/pubapi/v1/fs#{folder_path}").params(list_content: true, sort_by: 'name')
if response['is_folder']
path << response['folders']&.map { |folder| [folder['name'].labelize, folder['path'].gsub(' ', '%20'), nil, true] }
path << response['files']&.map { |file| [file['name'].labelize, file['path'].gsub(' ', '%20'), nil, false] } if response['files'].present?
Array.wrap(path.compact).flatten(1)
end
else
# Get root folders
get('/pubapi/v1/fs/')['folders']&.map do |folder|
[folder['name'].labelize, folder['path'].gsub(' ', '%20'), nil, true]
end
end
end,
}
```

In the above case, we have wanted to only allow users to select files to be downloaded. However, in a variety of cases, you might want to allow users to also select folders (the nodes) as you want them to provide a path to a folder instead of a file. This can be configured like below:
```ruby
input_fields: lambda do |_object_definitions|
[
{
name: 'path',
label: 'Folder path',
optional: false,
control_type: 'tree',
pick_list: 'folder_path',
tree_options: {
selectable_folder: true
}
},
]
end
```
Another variation is when you need to allow end users to select multiple folders. This can be configured like below:
```ruby
input_fields: lambda do |_object_definitions|
[
{
name: 'path',
label: 'Folder path',
optional: false,
control_type: 'tree',
pick_list: 'folder_path',
tree_options: {
selectable_folder: true,
multi_select: true,
force_selection_hierarchy: true # Setting this to true causes all child nodes to be selected when the parent is selected.
}
},
]
end
```
```
### references/sdk-reference__http.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/http.html
> **Fetched**: 2026-01-18T02:50:29.243202
---
# [#](<#http-methods>) HTTP Methods
In this section we cover the various HTTP methods that Workato supports. You should already be familiar with most of them. We also cover how you can do post-response processing of your HTTP calls to manipulate data into formats that are easier to use later on in your connector code.
## [#](<#http-verb-methods>) HTTP verb methods
HTTP verb | Method | Example
---|---|---
GET | `get()` | `get("url", parameters)`
POST | `post()` | `post("url", payload)`
PUT | `put()` | `put("url", payload)`
PATCH | `patch()` | `patch("url", payload)`
DELETE | `delete()` | `delete("url", parameters)`
OPTIONS | `options()` | `options("url", parameters)`
## [#](<#forming-a-request>) Forming a request
Each HTTP verb method must be provided a `url` string as the first argument. The second argument (optional) can be in 2 forms.
Firstly, `input` can be passed as a single hash. This hash can simply be the `input` argument of the `execute` or `poll` argument, such as the following:
```ruby
execute: lambda do |connection, input|
get("https://www.some_api_endpoint.com/api", input)
end
```
The hash can also be formed before like this:
```ruby
execute: lambda do |connection, input|
params = {
"id" => input["id"]
}
get("https://www.some_api_endpoint.com/api", params)
end
```
The Workato SDK framework processes this hash value and transforms it into the respective data format. For GET, DELETE OPTIONS requests, the hash data is converted to URL query parameters.
For POST, PUT, and PATCH, the payload is formed into the request body into a format that you specify. Learn how to work with the various data formats [here](</developing-connectors/sdk/guides/data-formats.html>).
The other method of passing request data is as a series of key/value pairs.
```ruby
execute: lambda do |connection, input|
post("https://www.some_api_endpoint.com/api", name: input["name"], email: input["email"])
end
```
All arguments after the first will be transformed into request data. In this case, since the default data format is JSON, the following request body is formed:
```ruby
{
"name": "Ee Shan",
"email": "[[email protected]](</cdn-cgi/l/email-protection>)"
}
```
For a GET request, the following URL parameters are formed.
```ruby
execute: lambda do |connection, input|
get("https://www.some_api_endpoint.com/api", name: input["name"], email: input["email"])
end
```
The full request URL string will be:
```ruby
https://www.some_api_endpoint.com/api?name%3DEe%20Shan%26email%3Deeshan%40workato.com
```
AUTHENTICATION APPENDS TO THE REQUEST URL
Any authentication you define is appended to the request URL. The preceding example assumes no authentication is required. Authentication is applied through the `apply` block defined in the `connection` object.
## [#](<#additional-helper-methods-to-form-requests>) Additional helper methods to form requests
You may use a variety of other helper methods on Workato by chaining them after the initial HTTP verb method. Here are some methods that might be useful:
### [#](<#payload>) payload
This method allows you to add a payload to a request and follows the same syntax that we covered above.
```ruby
execute: lambda do |connection, input|
post("https://www.some_api_endpoint.com/api")
.payload(name: input["name"], email: input["email"])
end
```
Resulting the payload of the post request:
```ruby
{
"name": "Ee Shan",
"email": "[[email protected]](</cdn-cgi/l/email-protection>)"
}
```
## [#](<#params>) params
This method allows you to add a query parameters to a request and follows the same syntax that we covered above. These values will be URL-encoded.
```ruby
execute: lambda do |connection, input|
get("https://www.some_api_endpoint.com/api")
.params(name: input["name"], email: input["email"])
end
```
```ruby
https://www.some_api_endpoint.com/api?name%3DEe%20Shan%26email%3Deeshan%40workato.com
```
## [#](<#headers>) headers
This method allows you to add a headers to a request and follows the same syntax that we covered above. Headers defined here **are not case sensitive.**
```ruby
execute: lambda do |connection, input|
get("https://www.some_api_endpoint.com/api")
.headers(Authorization: "Bearer HTB674HJK1")
end
```
TIP
Whilst case sensitive headers are a departure from [RFC (opens new window)](<http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2>), you may use them in your HTTP methods through the method `case_sensitive_headers` in place of `headers`.
## [#](<#tls-client-cert>) tls_client_cert
This method allows you to add SSL certs, keys, passphrases, and intermediates certs.
```ruby
execute: lambda do |connection, input|
get("https://www.some_api_endpoint.com/api")
.tls_client_cert(
certificate: connection['ssl_client_cert'],
key: connection['ssl_client_key'],
passphrase: connection['ssl_key_passphrase'],
intermediates: connection['ssl_client_intermediate_cert']
)
end
```
## [#](<#post-response-processing>) Post-response processing
### [#](<#default-response-data>) Default response data
By default, all HTTP verb methods will return the response body of the request. For example, the following request creates a user in **Okta**.
```ruby
execute: lambda do |connection, input|
response = post("/api/v1/users", profile: { login: input["email"], displayName: input["name"] })
end
```
`response` variable will a hash that looks like this:
```ruby
{
"id": "00ub0oNGTSWTBKOLGLNR",
"status": "STAGED",
"created": "2018-03-13T21:36:25.344Z",
"activated": null,
"statusChanged": null,
"lastLogin": null,
"lastUpdated": "22018-03-13T21:36:25.344Z",
"passwordChanged": null,
"profile": {
"firstName": "Ee Shan",
"lastName": "Sim",
"email": "[[email protected]](</cdn-cgi/l/email-protection>)",
"login": "[[email protected]](</cdn-cgi/l/email-protection>)",
"mobilePhone": null
},
"credentials": {
"provider": {
"type": "OKTA",
"name": "OKTA"
}
}
}
```
### [#](<#response-handling>) Response handling
`after_response` is an optional block that can be chained to the HTTP verb methods to handle the various parts of a HTTP response. Let's take a look at an example, again using the **Okta** API.
When a request is sent to the [List all users (opens new window)](<https://developer.okta.com/docs/api/resources/users#list-all-users>) endpoint, the truncated response looks like this.
```ruby
HTTP/1.1 200 OK
Content-Type: application/json
Link: <https://workatotest.okta.com/api/v1/users?limit=200>; rel="self"
[
{
"id": "00utti9t3j1xO9jOm2p6",
"status": "ACTIVE",
"created": "2018-03-15T08:23:05.000Z",
"activated": null,
"statusChanged": "2018-03-15T08:39:39.000Z",
"lastLogin": "2018-03-15T08:39:40.000Z",
"lastUpdated": "2018-03-15T08:39:40.000Z",
"passwordChanged": "2018-03-15T08:39:39.000Z",
"profile": {},
"credentials": {},
"_links": {}
}
]
```
This response can be broken down into 3 parts. The HTTP response **code** , **header** , and **body**.
`after_response` can be used to handle all these parts of the HTTP response. Suppose I have an action that lists all users and outputs the entire response, including the link to the existing page from the header.
```ruby
execute: lambda do |connection, input|
get("/api/v1/users").after_response do |code, body, headers|
{
code: code,
next_link: headers["link"],
users: body
}
end
end
```
The resultant output of this action will contain all 3 parts of the response.
```ruby
{
"code": 200,
"next_link": "<https://workatotest.okta.com/api/v1/users?limit=200>; rel=\"self\"",
"users": [
{
"id": "00utti9t3j1xO9jOm2p6",
"status": "ACTIVE",
"created": "2018-03-15T08:23:05.000Z",
"activated": null,
"statusChanged": "2018-03-15T08:39:39.000Z",
"lastLogin": "2018-03-15T08:39:40.000Z",
"lastUpdated": "2018-03-15T08:39:40.000Z",
"passwordChanged": "2018-03-15T08:39:39.000Z",
"profile": {},
"credentials": {},
"_links": {}
}
]
}
```
### [#](<#testing>) Testing
You can easily verify this while developing your custom connector. When you include post-request handling, the output tab should reflect the expected JSON object.
 _Output with response code and header values_
```
### references/sdk-reference__ruby_methods.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/ruby_methods.html
> **Fetched**: 2026-01-18T02:50:34.125656
---
# [#](<#available-ruby-methods>) Available Ruby methods
Workato implements a subset of Ruby's public instance methods within its SDK framework. This document lists the Ruby methods that are available when building your connectors. You can request to add additional methods to this list using the [Workato feedback widget (opens new window)](<https://ideas.workato.com/app/#/login>).
WHITELIST REMOVAL
Workato has removed whitelisting for its SDK framework, starting March 2025. This means that developers can now access the full functionality of Ruby 2.7, including built-in libraries, and any available Ruby gems in the SDK container. This change significantly expands the range of capabilities SDK developers can leverage within the platform.
[Learn more](</developing-connectors/sdk/sdk-reference/whitelist-removal.html>) about the capabilities available with the removal of ruby whitelisting.
This enhancement doesn't apply to the Ruby code connector.
PERSONAL REUSABLE METHODS
You can declare personal reusable methods to use in any block when using Workato SDK.
* * *
## [#](<#at>) at
Creates a new time object with the given argument.
See [at (opens new window)](<https://apidock.com/ruby/Time/at/class>) method definition.
* * *
## [#](<#abs>) abs
Returns the absolute value of a number.
* * *
## [#](<#account-property>) account_property
Returns the value for a specific account property in the user's workspace.
```ruby
client_secret = account_property('hubspot_webhook_client_secret')
```
Note that you can only invoke this method from the following lambdas within the `connection` hash:
* `authorization_url`
* `token_url`
* `acquire`
* `base_uri`
Also, other lambdas within `actions`, `triggers`, `methods`, `object_definitions`, and `pick_lists`.
* * *
## [#](<#aes-cbc-encrypt>) aes_cbc_encrypt
AES encryption with CBC mode. Accepts 128, 192, and 256-bit keys.
```ruby
key128 = workato.pbkdf2_hmac_sha1("password", workato.random_bytes(8))
workato.aes_cbc_encrypt("text_to_encrypt", key128)
```
* * *
## [#](<#aes-cbc-decrypt>) aes_cbc_decrypt
AES decryption with CBC mode. Accepts 128, 192, and 256-bit keys.
```ruby
workato.aes_cbc_decrypt("text_to_decrypt", key128)
```
* * *
## [#](<#aes-gcm-encrypt>) aes_gcm_encrypt
Returns an AES encrypted string and auth tag using GCM mode. The initialization vector (IV) key size must be 12 bytes. Accepts 128, 192, and 256-bit keys.
```bash
# Generate a salt for key derivation
salt = workato.random_bytes(8)
# Derive a key using PBKDF2 with HMAC-SHA1
key128 = workato.pbkdf2_hmac_sha1("password", salt)
# Initialize an IV (initialization vector)
iv = "init_vector0"
# Encrypt the text
encrypted_data = workato.aes_gcm_encrypt("text_to_encrypt", key128, iv) # [0x3040ffe9e51d4a929605fe0a262eea, 0x0f7e0a05eb25512c03ffafca43418a12]
```
You can also provide `auth_data`, which accepts a string value:
```ruby
auth_data = "my_auth_data"
# Generate a salt for key derivation
salt = workato.random_bytes(8)
# Derive a key using PBKDF2 with HMAC-SHA1
key128 = workato.pbkdf2_hmac_sha1("password", salt)
# Initialize an IV (initialization vector)
iv = "init_vector0"
# Encrypt the text
encrypted_data = workato.aes_gcm_encrypt("text_to_encrypt", key128, iv, auth_data) # [0x3040ffe9e51d4a929605fe0a262eea, 0x0f7e0a05eb25512c03ffafca43418a12]
```
The result is an array in the form `[encrypted_string, auth_tag]`. Use the [`.first`](<#first>) and [`.last`](<#last>) formulas to retrieve these values individually.
* * *
## [#](<#aes-gcm-decrypt>) aes_gcm_decrypt
Returns an AES decrypted string using GCM mode. The initialization vector (IV) key size must be 12 bytes. Accepts 128, 192, and 256-bit keys.
```ruby
decrypted_string = workato.aes_gcm_decrypt(encrypted_string, key128, auth_tag, iv) # 0x746578745f746f5f656e6372797074
```
If you encrypted with `auth_data`, you must include it in the formula:
```ruby
decrypted_string = workato.aes_gcm_decrypt(encrypted_string, key128, auth_tag, iv, auth_data) # 0x746578745f746f5f656e6372797074
```
The output is a raw byte sequence in hexadecimal format. You can append the [`.as_utf8`](<#as_utf8>) formula to decode it into a UTF-8 string:
```ruby
decrypted_string = workato.aes_gcm_decrypt(encrypted_string, key128, auth_tag, iv, auth_data).as_utf8 # "text_to_encrypt"
```
* * *
## [#](<#after-error-response>) after_error_response
Can be chained with an HTTP request to rescue a failed request. See [Error handling](</developing-connectors/sdk/guides/error-handling.html>).
* * *
## [#](<#after-response>) after_response
Can be chained with an HTTP request to utilize the response's headers, and so on. See [Error handling](</developing-connectors/sdk/guides/error-handling.html>).
* * *
## [#](<#ago>) ago
Go back in time. Returns timestamp.
```ruby
2.days.ago #2017-01-15T12:30:00.000000-07:00 if time now is 2017-01-17T12:30:00.000000-07:00
30.minutes.ago #2017-01-15T12:30:00.000000-07:00 if time now is 2017-01-15T13:00:00.000000-07:00
30.seconds.ago #2017-01-15T12:30:00.000000-07:00 if time now is 2017-01-15T12:30:30.000000-07:00
```
See [ago (opens new window)](<https://apidock.com/rails/ActiveSupport/Duration/ago>) method definition.
* * *
## [#](<#all>) all?
Passes each element of the collection to the given block. The method returns true if the block never returns false or nil.
```ruby
%w[ant bear cat].all? { |word| word.length >= 3 } #=> true
```
See [all?](<hhttps://apidock.com/ruby/Enumerable/all%3F>) method definition.
* * *
## [#](<#as-string>) as_string
Decode byte sequence as a string in the given encoding.
```ruby
"0J/RgNC40LLQtdGC\n".decode_base64.as_string('utf-8')
```
* * *
## [#](<#as-utf8>) as_utf8
Decode byte sequence as a UTF-8 string.
```ruby
"0J/RgNC40LLQtdGC\n".decode_base64.as_utf8
```
* * *
## [#](<#aws-generate-signature>) aws.generate_signature
Generates an AWS V4 Signature for AWS services and returns a hash that contains the URL and signature for you to formulate the request.
```ruby
aws.generate_signature(
connection: connection,
service: "s3",
region: connection["aws_region"],
host: "s3.dualstack.#{connection['aws_region']}.amazonaws.com",
method: "GET",
path: "/demo",
params: {
"list-type": 2,
"max-keys": 1000
}.compact,
headers: {
Test: "hello!"
},
payload: {
hello: "world"
}.to_json
)
```
See [AWS authentication](</developing-connectors/sdk/guides/authentication/aws_auth.html>).
* * *
## [#](<#blank>) blank?
Returns true if value is null or an empty string, otherwise false.
* * *
## [#](<#binary>) binary?
Returns true if value is a binary array.
* * *
## [#](<#beginning-of-hour>) beginning_of_hour
Returns timestamp for top-of-the-hour for given timestamp.
```ruby
"2017-06-01T16:56:00.000000-07:00".to_time.beginning_of_hour #2017-06-01T16:00:00.000000 +0000
```
* * *
## [#](<#beginning-of-day>) beginning_of_day
Returns timestamp for midnight for given timestamp.
```ruby
"2017-06-08T22:30:10.000000-07:00".to_time.beginning_of_day #2017-06-08T00:00:00.000000 +0000
```
* * *
## [#](<#beginning-of-week>) beginning_of_week
Returns timestamp for midnight at the start of the week (Mon) for the given timestamp.
```ruby
"2017-08-18T00:00:00.000000-07:00".to_time.beginning_of_week #2017-08-14T00:00:00.000000 +0000
```
* * *
## [#](<#beginning-of-month>) beginning_of_month
Returns timestamp for midnight for the start of the month for the given timestamp.
```ruby
"2017-01-30T22:35:00.000000-07:00".to_time.beginning_of_month #2017-01-01T00:00:00.000000 +0000
```
* * *
## [#](<#beginning-of-year>) beginning_of_year
Returns timestamp for midnight for the start of the year for a given timestamp.
```ruby
"2017-01-30T22:35:00.000000 -07:00".to_time.beginning_of_year #2017-01-01T00:00:00.000000 +0000
```
* * *
## [#](<#bytes>) bytes
Returns an array of bytes for a given string.
```ruby
"Hello".bytes # ["72","101","108","108","111"]
```
* * *
## [#](<#bytesize>) bytesize
Returns the length of a given string in bytes.
```ruby
"Hello".bytesize # 5
```
* * *
## [#](<#byteslice>) byteslice
Returns a substring of specified bytes instead of length. In some cases, non-ASCII characters (for example, Japanese and Chinese characters) may use multiple bytes.
```ruby
"abc漢字".byeslice(0,4) # "abc漢"
```
See [byteslice (opens new window)](<https://apidock.com/ruby/String/byteslice>) method definition.
* * *
## [#](<#capitalize>) capitalize
Capitalizes the first character of the string.
* * *
## [#](<#case-sensitive-headers>) case_sensitive_headers
Can be chained with HTTP methods to introduce headers that are case-sensitive. By default, Workato does not respect case sensitivity for headers, as per RFC specification.
```ruby
get("https://www.example.com").case_sensitive_headers("HeLlo": "world")
```
* * *
## [#](<#checkpoint>) checkpoint!
Similar to `reinvoke_after`, the `checkpoint!` method is used with file stream consuming actions. When invoked, Workato checks the duration of the action's execution. If it exceeds 120 seconds, Workato refreshes the action level timeout with a slight delay to ensure fair processing.
This allows you to transfer files that exceed the current 180-second timeout limit.
* * *
## [#](<#chunk>) chunk
Enumerates over the items, chunking them together based on the return value of the block.
See [chunk (opens new window)](<https://apidock.com/ruby/Enumerable/chunk>) method definition.
* * *
## [#](<#chunk-while>) chunk_while
Creates an enumerator for each chunked element. The beginnings of chunks are defined by the block.
See [chunk_while (opens new window)](<https://apidock.com/ruby/Enumerable/chunk_while>) method definition.
* * *
## [#](<#collect>) collect
Returns a new array with the results of running block once for every element in enum.
See [collect (opens new window)](<https://apidock.com/ruby/Array/collect>) method definition.
* * *
## [#](<#collect-concat>) collect_concat
Returns a new array with the concatenated results of running block once for every element in enum.
See [collect_concat (opens new window)](<https://apidock.com/ruby/Enumerable/collect_concat>) method definition.
* * *
## [#](<#compact>) compact
Returns a hash with non nil values.
See [compact (opens new window)](<https://apidock.com/rails/Hash/compact>) method definition.
* * *
## [#](<#count>) count
Returns the number of elements in an array that match the given value.
```ruby
["apple", "orange", "apple", "banana", "apple"].count("apple")
```
For more details, refer to the [count (opens new window)](<https://apidock.com/ruby/Array/count>) method definition.
* * *
## [#](<#csv-parse>) csv.parse
Allows you to parse a CSV string into a JSON array that makes it easy to display as datapills.
```ruby
workato.csv.parse("blue;1\nwhite;2\n", headers: "color;count", col_sep: ";")
```
Takes seven arguments:
* string
* The first position of the method which represents the CSV string to parse.
* headers
* Either `true` (First row of actual CSV will be used as headers), `array` of `string` (corresponding to each column header) or `string` (Artificial first row of the CSV with appropriate column separator).
* col_sep
* The column separator in the CSV. Defaults to `,`.
* row_sep
* The row separator in the CSV. Defaults to `\n`.
* quote_char
* The quoting character in the CSV. Defaults to double quotes `"`.
* skip_blanks
* Boolean that indicates whether blank lines in the string input should be ignored. Defaults to false.
* skip_first_line
* Boolean that indicates if we should skip the first line. Useful when `headers` is true.
**Limits:** File size must be less than 30 MB and CSV lines fewer than 65K.
* * *
## [#](<#csv-generate>) csv.generate
Allows you to generate a CSV string from a JSON array so you can send it to a downstream system as a file.
```ruby
workato.csv.generate(headers: ["color", "amount"], col_sep: ";") do |csv|
csv << [:blue, 1]
csv << [:white, 2]
end
```
Takes five arguments:
* headers
* Either `true` (First row of actual CSV will be used as headers), `array` of `string` (corresponding to each column header) or `string` (Artificial first row of the CSV with appropriate column separator).
* col_sep
* The column separator in the CSV. Defaults to `,`.
* row_sep
* The row separator in the CSV. Defaults to `\n`.
* quote_char
* The quoting character in the CSV. Defaults to double quotes `"`.
* force_quotes
* Boolean that determines whether each output field should be quoted.
Finally, one lambda that allows you to append individual rows to this CSV as an array of strings.
* * *
## [#](<#cycle>) cycle
Cycles through an array for a specified number of times and calls a block for each element.
See [cycle (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/cycle>) method definition.
* * *
## [#](<#decode-base64>) decode_base64
Decode using Base64 algorithm.
* * *
## [#](<#decode-hex>) decode_hex
Decode hexadecimal into binary string.
* * *
## [#](<#decode-url>) decode_url
URL decode a string. This formula uses `CGI.unescape` to URL decoding.
* * *
## [#](<#decode-urlsafe-base64>) decode_urlsafe_base64
Decode using URL-safe modification of Base64 algorithm.
* * *
## [#](<#decrypt>) decrypt
Decrypt the encrypted string using AES-256-CBC algorithm. Input should be in RNCryptor V3 format.
This method returns a byte array instead of a string. You can convert the decrypt method output to a string by appending the [`.as_string()`](<#as-string>) or [`.as_utf8`](<#as-utf8>) function to your formula.
* * *
## [#](<#deep-merge>) deep_merge
Merges a hash with another hash, including nested child hashes.
See [deep_merge (opens new window)](<https://apidock.com/rails/Hash/deep_merge>) method definition.
* * *
## [#](<#delete-at>) delete_at
Delete elements in an array.
See [delete_at (opens new window)](<https://apidock.com/ruby/Array/delete_at>) method definition.
* * *
## [#](<#detect>) detect
Passes each element in an array to a block. Returns the first element that satisfies a block.
See [detect (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/detect>) method definition.
* * *
## [#](<#dig>) dig
Retrieves the value object corresponding to the index passed in.
The `dig` method is often used to strip away layers in nested arrays/hashes. For example, we use the `dig` method often when dealing with XML data formats.
See [dig (opens new window)](<https://apidock.com/ruby/Array/dig>) method definition.
* * *
## [#](<#drop>) drop
Drops first N elements from an Enumerator and returns the rest of the elements in an array.
```ruby
[1, 2, 3, 4, 5, 0].drop(3) #=> [4, 5, 0]
```
See [drop (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/drop>) method definition.
* * *
## [#](<#drop-while>) drop_while
Drops elements up to, but not including, the first element of an array for which the block returns nil or false.
See [drop_while (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/drop_while>) method definition.
* * *
## [#](<#dst>) dst?
Returns true if the time is within Daylight Savings Time for the specified time zone.
* * *
## [#](<#each>) each
Basic iterator.
```ruby
[1, 2, 3].each { |i| puts i }
```
* * *
## [#](<#each-byte>) each_byte
Passes each byte in a given string to the given block, or returns an enumerator if no block is given.
See [each_byte (opens new window)](<https://apidock.com/ruby/v2_5_5/String/each_byte>) method definition.
* * *
## [#](<#each-char>) each_char
Passes each character in a given string to the given block. Returns an enumerator if no block is given.
See [each_char (opens new window)](<https://apidock.com/ruby/String/each_char>) method definition.
* * *
## [#](<#each-cons>) each_cons
Iterates the given block for each array of consecutive N elements. If no block is given, returns an enumerator.
See [each_cons (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/each_cons>) method definition.
* * *
## [#](<#each-entry>) each_entry
Iterates over an array and returns each element in the block.
See [each_entry (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/each_entry>) method definition.
* * *
## [#](<#each-slice>) each_slice
Iterates the given block for each slice of N elements. If no block is given, returns an enumerator.
See [each_slice (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/each_slice>) method definition.
* * *
## [#](<#each-with-index>) each_with_index
Iterator returned with an index.
```ruby
[1, 2, 3].each_with_index { |item, index| puts "#{index}:#{item}" }
```
See [each_with_index (opens new window)](<https://apidock.com/ruby/Enumerator/each_with_index>) method definition.
* * *
## [#](<#each-with-object>) each_with_object
Iterator returned with an object which you can define.
```ruby
[%w(foo bar)].each_with_object({}) { |str, hsh| hsh[str] = str.upcase }
# => {'foo' => 'FOO', 'bar' => 'BAR'}
```
See [each_with_object (opens new window)](<https://apidock.com/rails/Enumerable/each_with_object>) method definition.
* * *
## [#](<#encode-hex>) encode_hex
Converts binary string to its hex representation.
```ruby
"0J/RgNC40LLQtdGC\n".decode_base64.encode_hex
```
* * *
## [#](<#encode-sha256>) encode_sha256
Encode using SHA256 algorithm. The output is a binary string. Use `encode_hex` to convert to a hex representation.
```ruby
"hello".encode_sha256 #=> 0x2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
"hello".encode_sha256.encode_hex #=> 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
```
* * *
## [#](<#encode-sha512>) encode_sha512
Encode using SHA512 algorithm. The output is a binary string. Use `encode_hex` to convert to a hex representation.
```ruby
"hello".encode_sha512 #=> 0x9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
"hello".encode_sha512.encode_hex #=> 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
```
* * *
## [#](<#encode-base64>) encode_base64
Encode using Base64 algorithm.
* * *
## [#](<#encode-url>) encode_url
URL encode a string.
```ruby
'Hello World'.encode_url # 'Hello%20World'
```
* * *
## [#](<#encode-urlsafe-base64>) encode_urlsafe_base64
Encode using URL-safe modification of Base64 algorithm.
* * *
## [#](<#encode-www-form>) encode_www_form
Join hash into URL-encoded string of parameters.
```ruby
{"apple" => "red green", "2" => "3"}.encode_www_form #"apple=red+green&2=3"
```
* * *
## [#](<#ends-of-month>) ends_of_month
Returns a new date/time representing the end of the month.
```ruby
"2017-08-18T00:00:00".to_time.end_of_month #2017-08-31 23:59:59 +0000
```
* * *
## [#](<#ends-with>) ends_with?
Returns true if string ends with a specific pattern. False otherwise.
```ruby
"Hello!".ends_with?("!") #true
```
* * *
## [#](<#entries>) entries
Returns an array containing the items in enum.
```ruby
(1..7).entries #=> [1, 2, 3, 4, 5, 6, 7]
{ 'a'=>1, 'b'=>2, 'c'=>3 }.entries #=> [["a", 1], ["b", 2], ["c", 3]]
```
See [entries (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/entries>) method definition.
* * *
## [#](<#error>) error
Raise a job error with a user-defined error body.
```ruby
error("Unable to find Account with ID: 123")
```
* * *
## [#](<#even>) even?
Returns true if integer is an even number.
See [even? (opens new window)](<https://apidock.com/ruby/Integer/even%3F>) method definition.
* * *
## [#](<#except>) except
Returns a hash that includes everything except given keys.
```ruby
{ name: "Jake", last_name: "Paul", age: "22" }.except(:name, :last_name) # { :age => "22" }
```
See [except (opens new window)](<https://apidock.com/rails/Hash/except>) method definition.
* * *
## [#](<#exclude>) exclude?
Returns true if field does not contain a value. Case sensitive.
```ruby
"Partner account".exclude?("Partner") #false
```
See [exclude (opens new window)](<https://apidock.com/rails/String/exclude%3F>) method definition.
* * *
## [#](<#execution-context>) execution_context
RESTRICTED METHOD AVAILABILITY
This method is available only to connectors built within Embedded partner workspaces. It returns a hash containing the context of the recipe and job from which this action or trigger is invoked. If there is no applicable context, for example, the job ID when a request is sent in a trigger, the key's value is `null`.
The following table summarizes the lambdas: `execution_context` return values:
Key | recipe_id | job_id
---|---|---
execute | Yes | Yes
methods (For each method called within execute) | Yes | Yes
apply (For requests sent in the execute lambda) | Yes | Yes
poll | Yes | No
methods (For each method called within poll) | Yes | No
apply (For requests sent in the poll lambda) | Yes | No
object_definitions (For each fields method defined) | No | No
pick_lists (For each pick_list method defined) | No | No
methods (For each method called within pick_lists or object_definitions) | No | No
You can reference the execution context using the `execution_context` method.
```ruby
execution_context #=> { :recipe_id => "1234", :job_id => "j-ATh8ngzP-f69ak9" }
execution_context[:recipe_id] #=> "1234"
execution_context[:job_id] #=> "j-ATh8ngzP-f69ak9"
```
* * *
## [#](<#fetch>) fetch
Returns a value from the hash for the given key.
See [fetch (opens new window)](<https://apidock.com/ruby/Hash/fetch>) method definition.
* * *
## [#](<#find-all>) find_all
Returns an array containing all elements of a hash or array that satisfy the condition denoted in the block.
```ruby
Foo = { :abc => 1, :bad => [1,2] }
Foo.find_all { |i| i[0] == :abc } # [[:abc, 1]]
```
See [find_all (opens new window)](<https://apidock.com/ruby/Enumerable/find_all>) method definition.
* * *
## [#](<#find-index>) find_index
Compares each element in an array to a given block and returns the index for the first match.
```ruby
(1..100).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> 34
```
See [find_index (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/find_index>) method definition.
* * *
## [#](<#first>) first
Returns the first item in a list. Can also be used to return the first n items in a list.
See [first (opens new window)](<https://apidock.com/ruby/Array/first>) method definition.
* * *
## [#](<#flatten>) flatten
Flatten multi-dimensional array to simple array.
```ruby
[[1, 2, 3],[4,5,6]].flatten #[1, 2, 3, 4, 5, 6]
```
See [flatten (opens new window)](<https://apidock.com/ruby/Array/flatten>) method definition.
* * *
## [#](<#flat-map>) flat_map
Returns a new array with the concatenated results of running block once for every element in enum.
```ruby
[[1, 2], [3, 4]].flat_map { |e| e + [100] } #=> [1, 2, 100, 3, 4, 100]
```
See [flat_map (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/flat_map>) method definition.
* * *
## [#](<#follow-redirection>) follow_redirection
By default, we follow most 3XX redirect HTTP codes. In some cases, you may need to apply this to follow the redirect for any response code.
```ruby
action_with_follow_redirection: {
execute: lambda do |_connection, _input|
get('https://run.mocky.io/v3/41abc094-6b10-41a9-8201-b15146258b12').follow_redirection.after_response do |code, body, headers|
{
code: code,
body: body,
headers: headers
}
end
end
}
```
* * *
## [#](<#format-json>) format_json
Convert request to JSON format and expect response body in JSON format.
* * *
## [#](<#format-map>) format_map
Creates a new array of strings by applying a format to each item in the input array.
```ruby
[[{name: 'Jake', age: 23}].format_map('Name: %{name}, Age: %{age}') #['Name: Jake, Age: 23']
[[22, 45], [33, 88]].format_map('Id: %s, Count: %s') #['Id: 22, Count: 45', 'Id: 33, Count: 88']
['Alex', 'Hao', 'Kai'].format_map('Name: %s') #['Name: Alex', 'Name: Hao', 'Name: Kai']
```
See [format_map](</formulas/array-list-formulas.html#formatmap>) method definition.
* * *
## [#](<#format-xml>) format_xml
Convert request to XML format and expect response body in XML format.
Takes three arguments:
* root_element_name
* Adds a root element tag to your outgoing XML payload.
* namespaces
* Adds additional tags to your payload for namespaces.
* strip_response_namespaces
* Strips namespaces from XML responses.
* * *
## [#](<#from-now>) from_now
Go forward in time. Returns timestamp of the moment that the formula was executed, with the specified time period added in Pacific Time (UTC-8/UTC-7).
```ruby
4.months.from_now #2017-05-23T14:40:07.338328-07:00
2.days.from_now #2017-01-05T14:40:07.338328-07:00
30.minutes.from_now
12.seconds.from_now
```
* * *
## [#](<#from-xml>) from_xml
Converts XML string to hash.
```ruby
"<?xml version="1.0" encoding="UTF-8"?> <hash><foo type="integer"></foo></hash>".from_xml # { "hash": [ "foo": [ { "@type": "integer", "content!": "1" } ] ] }
```
* * *
## [#](<#grep>) grep
Searches through an enumerator for every element that satisfies your condition.
See [grep (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/grep>) method definition.
* * *
## [#](<#grep-v>) grep_v
Searches through an enumerator for every element that does not satisfy your condition.
See [grep_v (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/grep_v>) method definition.
* * *
## [#](<#group-by>) group_by
Group arrays into sets.
See [group_by (opens new window)](<http://apidock.com/rails/Enumerable/group_by>) method definition.
* * *
## [#](<#gsub>) gsub
Substitute a pattern with value. Case sensitive.
```ruby
"Jean Marie".gsub(/J/, "M") #"Mean Marie"
```
See [gsub (opens new window)](<https://apidock.com/ruby/String/gsub>) method definition.
* * *
## [#](<#has-key>) has_key?
Returns true if the given key is present in hash.
See [has_key? (opens new window)](<https://apidock.com/ruby/GDBM/has_key%3F>) method definition.
* * *
## [#](<#headers>) headers
Add headers to a request.
```ruby
.headers(Authorization: "Bearer HTB674HJK1")
```
* * *
## [#](<#hmac-md5>) hmac_md5
Creates HMAC_MD5 signature.
```ruby
"username:password:nonce".hmac_md5("key")
```
* * *
## [#](<#hmac-sha1>) hmac_sha1
Creates HMAC_SHA1 signature.
```ruby
"username:password:nonce".hmac_sha1("key")
```
* * *
## [#](<#hmac-sha256>) hmac_sha256
Creates HMAC_SHA256 signature.
```ruby
"username:password:nonce".hmac_sha256("key")
```
* * *
## [#](<#hmac-sha512>) hmac_sha512
Creates HMAC_SHA512 signature.
```ruby
"username:password:nonce".hmac_sha512("key")
```
* * *
## [#](<#ignore-redirection>) ignore_redirection
Allows you to stop a request from being redirected immediately. Commonly used in cases where your requests are redirected to a secondary site like AWS S3 to download a file. You will need to strip any authentication used in the apply: key using "current_url".
```ruby
action_with_ignore_redirection: {
execute: lambda do |_connection, _input|
get('https://run.mocky.io/v3/41abc094-6b10-41a9-8201-b15146258b12').ignore_redirection.after_response do |code, body, headers|
{
code: code,
body: body,
headers: headers
}
end
end
},
```
* * *
## [#](<#ignored>) ignored
Ignore a comma-separate list of fields.
```ruby
object_definition["user"].ignored("id", "created_at")
```
* * *
## [#](<#include>) include?
Returns true if field contains a value. False otherwise.
See [include? (opens new window)](<https://apidock.com/ruby/String/include%3F>) method definition.
* * *
## [#](<#inject>) inject
Combine elements in an array using an operation.
See [inject (opens new window)](<http://apidock.com/ruby/Enumerable/inject>) method definition.
* * *
## [#](<#insert>) insert
Insert elements into an array.
See [insert (opens new window)](<https://apidock.com/ruby/v2_5_5/Array/insert>) method definition.
* * *
## [#](<#in-time-zone>) in_time_zone
Converts the time to given time zone.
```ruby
"2017-09-06T18:30:15.671720-05:00".to_time.in_time_zone("America/Los_Angeles") #"2017-09-06T16:30:15.671720-07:00"
```
* * *
## [#](<#is-a>) is_a?
Returns true if class is the class of obj, or if class is one of the superclasses of obj or modules included in obj.
Workato currently supports the following classes:
* Array
* Hash
* Time
* String
* Integer
* Float
See [is_a? (opens new window)](<https://apidock.com/ruby/Object/is_a%3F>) method definition.
* * *
## [#](<#is-true>) is_true?
Converts a value to boolean and returns true if value is truthy.
* * *
## [#](<#is-not-true>) is_not_true?
Converts a value to boolean and returns true if value is not truthy.
* * *
## [#](<#iso8601>) iso8601
Convert a date/date-time variable to ISO8601 format.
* * *
## [#](<#join>) join
Join array elements into a string.
See [join (opens new window)](<https://apidock.com/ruby/Array/join>) method definition.
* * *
## [#](<#jwt-decode>) jwt_decode
Decodes a JSON web token (JWT) using one of the following algorithms:
* RS256
* RS384
* RS512
* HS256
* HS384
* HS512
* ES256
* ES384
* ES512
```ruby
workato.jwt_decode( "eyJhbGciO...", "PEM key", \'RS256\') # => {"payload" => {"sub"=>"123", "name"=>"John", ...}, "header" => {"typ"=>"JWT", "alg"=>"RS256"}}
workato.jwt_decode( "eyJhbGciO...", "PEM key", \'RS512\') # => {"payload" => {"sub"=>"123", "name"=>"John", ...}, "header" => {"typ"=>"JWT", "alg"=>"RS512"}}
workato.jwt_decode( "eyJhbGciO...", "my$ecretK3y", \'HS256\') # => {"payload" => {"sub"=>"123", "name"=>"John", ...}, "header" => {"typ"=>"JWT", "alg"=>"HS256"}}
```
* * *
## [#](<#jwt-encode>) jwt_encode
Creates a JSON web token (JWT) using one of the following algorithms:
* RS256
* RS384
* RS512
* HS256
* HS384
* HS512
* ES256
* ES384
* ES512
Adds other named parameters to the header, such as `kid` in the following example:
```ruby
workato.jwt_encode({ name: "John Doe" }, "PEM key", 'RS256') # => "eyJhbGciO..."
workato.jwt_encode({ name: "John Doe" }, "PEM key", 'RS512', kid: "24668") #=> "eyJ0eXAiO..."
workato.jwt_encode({ name: "John Doe" }, "my$ecretK3y", 'HS256', kid: "24668") #=> "eyJ0eXAiO..."
workato.jwt_encode({ name: "John Doe" }, "my$ecretK3y", 'HS256') #=> "eyJ0eXAiO..."
workato.jwt_encode({ name: "John Doe" }, "ECDSA Key", 'ES256') #=> "eyJhbGciOiJ..."
```
* * *
## [#](<#last>) last
Returns the last item in a list. Can also be used to return the last n items in a list.
See [last (opens new window)](<https://apidock.com/ruby/Array/last>) method definition.
* * *
## [#](<#ljust>) ljust
Aligns strings to the left and pads with whitespace or specified pattern until string is the required length.
```ruby
" test".ljust(10, "*") # " test*****"
```
See [ljust (opens new window)](<https://apidock.com/ruby/String/ljust>) method definition.
* * *
## [#](<#lookup>) lookup
Lookup a record from your lookup tables defined in Workato.
```ruby
lookup('States list', 'State code': 'AZ')['State name'] #"Arizona"
```
See [lookup](</formulas/other-formulas.html#lookup>) method definition.
* * *
## [#](<#lstrip>) lstrip
Remove white space from the beginning of string.
```ruby
" Test ".lstrip #"Test "
```
See [lstrip (opens new window)](<https://apidock.com/ruby/String/lstrip>) method definition.
* * *
## [#](<#map>) map
Returns a new array after invoking block on each element.
* * *
## [#](<#md5-hexdigest>) md5_hexdigest
Creates message digest using the MD5 Message-Digest Algorithm.
```ruby
"hello".md5_hexdigest #5d41402abc4b2a76b9719d911017c592
```
* * *
## [#](<#match>) match?
Returns true if a string contains a pattern. Case sensitive.
```ruby
"Jean Marie".match?(/Marie/) #true
```
* * *
## [#](<#max-by>) max_by
Returns the object in enum that gives the maximum value from the given block.
```ruby
%w(albatross dog horse).max_by { |x| x.length } # albatross
```
* * *
## [#](<#member>) member?
Alias of include?
See [member? (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/member%3F>) method definition.
* * *
## [#](<#merge>) merge
Returns a new hash containing merged contents.
See [merge (opens new window)](<https://ruby-doc.org/core-2.2.0/Hash.html#method-i-merge>) method definition.
* * *
## [#](<#minmax>) minmax
Returns a two element array which contains the minimum and the maximum value in the enumerable.
```ruby
a = %w(albatross dog horse)
a.minmax #=> ["albatross", "horse"]
a.minmax { |a, b| a.length <=> b.length }
#=> ["dog", "albatross"]
```
See [minmax (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/minmax>) method definition.
* * *
## [#](<#minmax-by>) minmax_by
Returns a two element array containing the objects in enum that correspond to the minimum and maximum values respectively from the given block.
```ruby
a = %w(albatross dog horse)
a.minmax_by { |x| x.length } #=> ["dog", "albatross"]
```
See [minmax_by (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/minmax_by>) method definition.
* * *
## [#](<#min-by>) min_by
Returns the object in enum that gives the minimum value from the given block
```ruby
a = %w(albatross dog horse)
a.min_by { |x| x.length } #=> "dog"
```
See [min_by (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/min_by>) method definition.
* * *
## [#](<#net-lookup>) net.lookup
Lookups specified DNS records for a given host.
```ruby
workato.net.lookup("www.google.com", "A") # => [{"address": "172.253.122.106"}, {"address":"172.253.122.103"}]
```
Takes two arguments:
* name
* The resource name such as the domain or host.
* Record Type
* Only supports "SRV" or "A" DNS record types
* * *
## [#](<#next>) next
Returns the next object in the enumerator, and move the internal position forward.
This is often used in config_fields where you can use `next` as a way to add a guard clause that checks inputs before the lambda function is executed.
```ruby
object_definitions: {
document: {
fields: lambda do |connection, config_fields, object_definitions|
next [] if config_fields.blank?
get("https://www.webmerge.me/api/documents/#{config_fields["document_id"]}/fields").map {
|field| field.slice("name")
}
end
}
}
```
See [next (opens new window)](<https://apidock.com/ruby/Enumerator/next>) method definition.
* * *
## [#](<#none>) none?
Passes each element of the collection to the given block. The method returns true if the block never returns true for all elements.
```ruby
%w{ant bear cat}.none? { |word| word.length == 5 } #=> true
```
See [none? (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/none%3F>) method definition.
* * *
## [#](<#now>) now
Returns timestamp of the moment that the formula was executed in Pacific Time (UTC-8/UTC-7).
```ruby
now #2017-01-23T14:04:53.365908-08:00
now + 2.days #2017-01-25T14:04:53.365908-08:00
```
* * *
## [#](<#odd>) odd?
Returns true if integer is an odd number. See [odd? (opens new window)](<https://apidock.com/ruby/Integer/odd%3F>) method definition.
* * *
## [#](<#one>) one?
Passes each element of the collection to the given block. The method returns true if the block returns true exactly once.
```ruby
[ nil, true, false ].one? #=> true
```
See [one? (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/one%3F>) method definition.
* * *
## [#](<#only>) only
White list a comma-separate of fields.
```ruby
object_definition["user"].only("id", "name")
```
* * *
## [#](<#ordinalize>) ordinalize
Turns a number into an ordinal string used to denote the position in an ordered sequence such as first, second, third, fourth.
```ruby
"1".ordinalize # "First"
```
* * *
## [#](<#pack>) pack
Packs contents of an array into a binary sequence.
See [pack (opens new window)](<https://apidock.com/ruby/Array/pack>) method definition.
* * *
## [#](<#parallel>) parallel
Accepts an array of requests and allows you to execute them in multiple threads.
```ruby
batches = (0..200).map do |batch|
post(url).headers(headers).request_body(payload)
end
results = parallel(batches, threads: 20)
```
See [Multi-threaded actions](</developing-connectors/sdk/guides/building-actions/multi-threaded-actions.html>) for more information.
* * *
## [#](<#parameterize>) parameterize
Replaces special characters in a string.
```ruby
"öüâ".parameterize #"oua"
```
* * *
## [#](<#params>) params
Add parameter to a request.
```ruby
.params(api_key: "HTB674HJK1")
```
* * *
## [#](<#parse-json>) parse_json
Works the same way as json.parse.
See [parse_json (opens new window)](<https://apidock.com/ruby/v1_9_3_392/JSON/parse>) method definition.
* * *
## [#](<#parse-yaml>) parse_yaml
Parse a YAML string. Supports true, false, nil, numbers, strings, arrays, hashes.
```ruby
workato.parse_yaml("---\nfoo: bar") # => { "foo" => "bar" }
```
* * *
## [#](<#payload>) payload
Add payload to a request.
```ruby
.payload(id: "345")
```
* * *
## [#](<#pbkdf2-hmac-sha1>) pbkdf2_hmac_sha1
Create keys of varying bit lengths using a password and a salt. Uses HMAC Sha1.
```ruby
key128 = workato.pbkdf2_hmac_sha1("password", workato.random_bytes(8))
key192 = workato.pbkdf2_hmac_sha1("password", workato.random_bytes(8), 1000, 24)
key256 = workato.pbkdf2_hmac_sha1("password", workato.random_bytes(8), 1000, 32)
```
* * *
## [#](<#pluck>) pluck
Select one or more attributes from an array of objects.
```ruby
[
{"id": 1, "name": "David"},
{"id": 2, "name": "Peter"}
].pluck("id")
```
Returns `[1, 2]`.
* * *
## [#](<#pluralize>) pluralize
Returns the plural form of the word in the string.
See [pluralize (opens new window)](<https://apidock.com/rails/String/pluralize>) method definition.
* * *
## [#](<#pop>) pop
Removes the last element from self and returns it, or nil if the array is empty.
If a number n is given, returns an array of the last n elements (or less) and removes it from array.
```ruby
a = [ "a", "b", "c", "d" ]
a.pop #=> "d"
a.pop(2) #=> ["b", "c"]
a #=> ["a"]
```
See [pop (opens new window)](<https://apidock.com/ruby/Array/pop>) method definition.
* * *
## [#](<#presence>) presence
Returns the value if present. Otherwise returns nil.
```ruby
nil.presence #nil
"".presence #nil
0.presence #0
```
See [presence (opens new window)](<https://apidock.com/rails/Object/presence>) method definition.
* * *
## [#](<#present>) present?
Returns true if the field has a value. False otherwise.
```ruby
nil.present? #false
"".present? #false
0.present? #true
```
See [present? (opens new window)](<https://apidock.com/rails/Object/present%3F>) method definition.
* * *
## [#](<#puts>) puts
Ruby version of `console.log` or `stdout`. Not the same as the `put` method.
Any output using the `puts` method shows up in the console log when testing in the code editor. Use this to aid in your debugging.
* * *
## [#](<#rand>) rand
Random number between 0 and 1.
* * *
## [#](<#random-bytes>) random_bytes
Generates a specified number of random bytes.
```ruby
workato.random_bytes(8)
```
* * *
## [#](<#reduce>) reduce
Combines all elements of enum by applying a binary operation, specified by a block or a symbol that names a method or operator.
```ruby
(5..10).reduce { |sum, n| sum + n } # 45
```
See [reduce (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/reduce>) method definition.
* * *
## [#](<#reinvoke-after>) reinvoke_after
Used in multistep actions that work with asynchronous APIs. Calling this method causes the job to pause for a specific interval before reinvoking the original `execute` lambda it is called in. Accepts `seconds` to denote how long the job should pause for, and `continue` which allows the job to be reinvoked with additional context.
```ruby
reinvoke_after(
seconds: step_time,
continue: {
current_step: current_step + 1,
jobid: response['jobReference']['jobId']
}
)
```
See [Multistep actions](</developing-connectors/sdk/guides/building-actions/multistep-actions.html>) for more information.
* * *
## [#](<#reject>) reject
Selectively returns elements for which the block returns false. Similar but opposite of **select**.
See [reject (opens new window)](<http://apidock.com/ruby/v1_9_3_392/Array/reject>) method definition.
* * *
## [#](<#render-yaml>) render_yaml
Render an object into a YAML string.
```ruby
workato.render_yaml({ "foo" => "bar" }) # => "---\nfoo: bar\n"
```
* * *
## [#](<#response-format-json>) response_format_json
Expect response in JSON format.
* * *
## [#](<#response-format-raw>) response_format_raw
Expect response in raw format. This can be chained after HTTP actions that expect binary data (such as PDFs and images) as responses.
* * *
## [#](<#response-format-xml>) response_format_xml
Expect response in XML format. Takes 1 argument.
* strip_response_namespaces
* Strips namespaces from XML responses.
* * *
## [#](<#request-format-json>) request_format_json
Convert request to JSON format.
* * *
## [#](<#request-format-multipart-form>) request_format_multipart_form
Convert request to multipart_form format.
* * *
## [#](<#request-format-raw>) request_format_raw
Convert request to raw format.
* * *
## [#](<#request-format-www-form-urlencoded>) request_format_www_form_urlencoded
Convert request to URL-encoded format.
* * *
## [#](<#request-format-xml>) request_format_xml
Convert request to XML format.
Takes two arguments:
* root_element_name
* Adds a root element tag to your outgoing XML payload.
* namespaces
* Adds additional tags to your payload for namespaces
## [#](<#required>) required
Make a comma-separate list of fields required.
```ruby
object_definition["user"].required("id", "created_at")
```
* * *
## [#](<#reverse>) reverse
Reverse string or array.
* * *
## [#](<#reverse-each>) reverse_each
Builds a temporary array and traverses that array in reverse order.
See [reverse_each (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/reverse_each>) method definition.
* * *
## [#](<#rjust>) rjust
Aligns string to right and pads with whitespace or pattern until string is specified length.
```ruby
"test".rjust(5) #" test"
"test".rjust(10, "*!") #"*!*!* test"
```
See [rjust (opens new window)](<https://apidock.com/ruby/String/rjust>) method definition.
* * *
## [#](<#round>) round
Round the number by regular rounding rules.
```ruby
11.99.round #12
11.555.round(2) #11.56
```
See [round (opens new window)](<https://apidock.com/ruby/Float/round>) method definition.
* * *
## [#](<#rsa-sha256>) rsa_sha256
Creates a RS256 signature (SHA256 hash signed with an RSA key)
```ruby
input['StringToSign'].rsa_sha256(rsa_private_key).base64
```
* * *
## [#](<#rsa-sha512>) rsa_sha512
Creates a RS512 signature (SHA512 hash signed with an RSA key).
```ruby
input['StringToSign'].rsa_sha512(rsa_private_key).base64
```
* * *
## [#](<#rstrip>) rstrip
Remove white space from the end of string.
```ruby
" Test ".rstrip #" Test"
```
See [rstrip (opens new window)](<https://apidock.com/ruby/String/rstrip>) method definition.
* * *
## [#](<#scan>) scan
Scans the string for a matching pattern.
```ruby
"Thu, 01/23/2014".scan(/\d+/).join("-") #01-23-2014
```
See [scan (opens new window)](<https://apidock.com/ruby/String/scan>) method definition.
* * *
## [#](<#scrub>) scrub
If the string is invalid byte sequence then replace invalid bytes with given replacement character, else returns self.
```ruby
"abc\u3042\x81".scrub("*") # "abc\u3042*"
```
See [scrub (opens new window)](<https://apidock.com/ruby/v2_5_5/String/scrub>) method definition.
* * *
## [#](<#select>) select
Selectively returns elements for which the block returns true.
See [select (opens new window)](<http://apidock.com/ruby/v1_9_3_392/Array/select>) method definition.
* * *
## [#](<#sha1>) SHA1
Encrypts a given string using the SHA1 encryption algorithm.
```ruby
"abcdef".sha1.encode_base64 # "H4rBDyPFtbwRZ72oS4M+XAV6d9I="
```
See [SHA1 (opens new window)](<https://ruby-doc.org/stdlib-2.4.0/libdoc/digest/rdoc/Digest/SHA1.html>) method definition.
* * *
## [#](<#singularize>) singularize
The reverse of `pluralize`. Returns the singular form of a word in a string.
```ruby
'posts'.singularize # => "post"
```
See [singularize (opens new window)](<https://apidock.com/rails/String/singularize>) method definition.
* * *
## [#](<#slice>) slice
Returns a substring of a given string, as defined by start indexes and length.
```ruby
"Jean Marie\.slice(0,3) #"Jea"
```
See [slice (opens new window)](<https://apidock.com/ruby/String/slice>) method definition.
* * *
## [#](<#slice-after>) slice_after
Slices an array after a specific value.
```ruby
["a", "b", "c"].slice_after("b").to_a # [["a", "b"], ["c"]]
```
See [slice_after (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/slice_after>) method definition.
* * *
## [#](<#slice-before>) slice_before
Slices an array before a specific value.
```ruby
["a", "b", "c"].slice_before("b").to_a # [["a"], ["b", "c"]]
```
See [slice_before (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/slice_before>) method definition.
* * *
## [#](<#slice-when>) slice_when
Creates an enumerator for each chunked elements.
```ruby
[1,2,4,9,10,11].slice_when { |i,j| i+1 != j}.to_a # [[1, 2], [4], [9, 10, 11]]
```
See [slice_when (opens new window)](<https://apidock.com/ruby/Enumerable/slice_when>) method definition.
* * *
## [#](<#smart-join>) smart_join
Join array to string. Removes empty and nil values. Trims the white space before joining.
```ruby
[nil, " ", " Hello ", " World "].smart_join(" ") #Hello World
```
See [smart_join](</formulas/array-list-formulas.html#smart-join>) method definition.
* * *
## [#](<#sort>) sort
Sort function returning new sorted array.
See [sort (opens new window)](<http://apidock.com/ruby/v1_9_3_392/Array/sort>) method definition.
* * *
## [#](<#sort-by>) sort_by
Sort function returning self.
See [sort_by (opens new window)](<https://apidock.com/ruby/Enumerable/sort_by>) method definition.
* * *
## [#](<#split>) split
Split string into an array by using defined pattern as delimiter.
```ruby
"Split string".split() #["Split", "string"]
"Split string".split("t") #["Spli", " s", "ring"]
```
See [split (opens new window)](<https://apidock.com/ruby/String/split>) method definition.
* * *
## [#](<#stream-out>) stream.out
Used in file stream producing actions that work with any of Workato's file streaming enabled connectors. Calling this method allows you to specify a `streaming` callback that is invoked when a downstream action downloads the file.
```ruby
workato.stream.out("download_file", { file_id: file_id })
```
See [file streaming](</developing-connectors/sdk/guides/building-actions/streaming.html>) for more information.
* * *
## [#](<#stream-in>) stream.in
Used in file stream consuming actions that work with any of Workato's file streaming enabled connectors. Calling this method allows you to specify a code block that can utilize a file stream to upload a file in chunks.
This method takes three arguments:
1. the first positional argument being the file contents from a previous action
2. `from` which is used to override the default offset of `0`. This will be used in implementing multi-step streaming
3. `frame_size` which is used to override the size requested from a stream producer.
```ruby
workato.stream.in(input["file"], from: previous_offset, frame_size: required_frame_size) do |chunk, starting_byte_range, ending_byte_range, eof, next_starting_byte_range|
put("/file/#{input['file_id']}").
headers("Content-Range": "byte #{starting_byte_range}-#{ending_byte_range}/*").
request_body(chunk).
presence
end
```
See [file streaming](</developing-connectors/sdk/guides/building-actions/streaming.html>) for more information.
* * *
## [#](<#strip>) strip
Strip white spaces from the beginning and the end of string.
```ruby
" This is an example ".strip #"This is an example"
```
See [strip (opens new window)](<https://apidock.com/ruby/String/strip>) method definition.
* * *
## [#](<#strip-tags>) strip_tags
Strip html tags from the string.
```ruby
"<html><body>Double bubble</body></html>".strip_tags #"Double bubble"
```
* * *
## [#](<#strftime>) strftime
Format date or time using %-placeholders.
* * *
## [#](<#sub>) sub
Substitute the first occurrence of a pattern with value.
```ruby
"Mean Marie".sub(/M/, "J") #"Jean Marie"
"Hello".sub(/[aeiou]/, "\*") #"H*llo"
```
* * *
## [#](<#suspend>) suspend
This method is used in [Wait for resume actions](</developing-connectors/sdk/guides/building-actions/wait-for-resume-actions.html>). These actions work with external systems that can send an API request when a long running process is complete. Calling this method suspends the job until Workato receives a corresponding request to its developer API, or until the specified suspension time expires.
```ruby
suspend(
continue: {
"state" => "suspended",
"url" => input['url']
},
expires_at: 10.minutes.from_now
)
```
* `continue`: This hash is passed to the `before_suspend`, `before_resume`, and `before_timeout_resume` lambdas.
* `expires_at`: This is the time in PST that the job waits for a request to resume. After this time, the job continues with a `timeout` call. The maximum timeout is 60 days.
* * *
## [#](<#take>) take
Returns first N elements from an array.
```ruby
[1, 2, 3, 4, 5, 0].take(3) #=> [1, 2, 3]
```
See [take (opens new window)](<https://apidock.com/ruby/v2_5_5/Enumerable/take>) method definition.
* * *
## [#](<#take-while>) take_while
Passes elements to the block until the block returns nil or false, then stops iterating and returns an array of all prior elements.
```ruby
[1, 2, 3, 4, 5, 0].take_while { |i| i < 3 } #=> [1, 2]
```
See [take_while (opens new window)](<https://apidock.com/ruby/Array/take_while>) method definition.
* * *
## [#](<#tap>) tap
Yields x to the block, and then returns x.
The `tap` method is often used for transformation. For example, we can use the `tap` method to transform a webhook's payload. Consider the following example:
```ruby
{
"id" => {"value" => 1},
"name" => {"value" => 2}
}
```
If a webhook payload is delivered in this format, you can use `tap` to transform it into a more user friendly JSON.
```ruby
webhook_notification: lambda do |input, payload|
payload.tap do |output|
output.each { |k, v| output[k] = v["value"] }
end
end
```
The final JSON will look as follows: `{"id"=>1, "name"=>2}`
See [tap (opens new window)](<https://apidock.com/ruby/Object/tap>) method definition.
* * *
## [#](<#tls-client-cert>) tls_client_cert
Allows you to dictate the TLS keys, TLS client, and intermediate certificates to be used in the request. Can be used by chaining it in a single request or used generally in the apply block.
```ruby
get("https://www.exampleapi.com").
tls_client_cert(
certificate: connection['ssl_client_cert'],
key: connection['ssl_client_key'],
passphrase: connection['ssl_key_passphrase'],
intermediates: connection['client_intermediate_certs'] # pass array if there are multiple intermediate certs
)
```
```ruby
apply: lambda do |connection|
tls_client_cert(
certificate: connection['ssl_client_cert'],
key: connection['ssl_client_key'],
passphrase: connection['ssl_key_passphrase'],
intermediates: connection['client_intermediate_certs'] # pass array if there are multiple intermediate certs
)
end
```
* * *
## [#](<#tls-server-certs>) tls_server_certs
Allows you to dictate the TLS server certificates we should accept during the SSL handshake process. This is useful for self-signed or untrusted root CA certificates. Can be used by chaining it in a single request or used generally in the apply block.
```ruby
get("https://www.exampleapi.com").
tls_server_certs(
certificates: [connection['server_ca_cert']], #additional intermediate server certificates can be given.
strict: false # Set to true to only allow requests from the given server CA cert.
)
```
```ruby
apply: lambda do |connection|
tls_server_certs(
certificates: [connection['server_ca_cert']], #additional intermediate server certificates can be given.
strict: false # Set to true to only allow requests from the given server CA cert.
)
end
```
* * *
## [#](<#to-currency>) to_currency
Convert to currency string.
```ruby
1234567890.50.to_currency # $1,234,567,890.50
```
* * *
## [#](<#to-currency-code>) to_currency_code
Convert alpha-2/3 country code or country name to ISO4217 currency code.
```ruby
"India".to_currency_code #INR
```
* * *
## [#](<#to-currency-name>) to_currency_name
Convert alpha-2/3 country code or country name to ISO4217 currency name.
```ruby
"India".to_currency_name #Rupees
```
* * *
## [#](<#to-currency-symbol>) to_currency_symbol
Convert alpha-2/3 country code or country name to ISO4217 currency symbol.
```ruby
"India".to_currency_symbol # ₨
```
* * *
## [#](<#to-country-alpha2>) to_country_alpha2
Convert alpha-3 country code or country name to alpha2 country code.
```ruby
"India".to_country_alpha2 #IN
"IND".to_country_alpha2 #IN
```
* * *
## [#](<#to-country-alpha3>) to_country_alpha3
Convert alpha-2 country code or country name to alpha3 country code.
```ruby
"Australia".to_country_alpha2 #AUS
"AU".to_country_alpha2 #AUS
```
* * *
## [#](<#to-country-name>) to_country_name
Convert alpha-2/3 country code or country name to ISO3166 country name.
```ruby
"GB".to_country_name #United Kingdom
"GBR".to_country_name #United Kingdom
```
* * *
## [#](<#to-country-number>) to_country_number
Convert alpha-2/3 country code or country name to ISO3166 country numeric code.
```ruby
"India".to_country_number #356
```
* * *
## [#](<#to-date>) to_date
Convert string or timestamp to date. Can be formatted.
```ruby
"12/24/2014 10:30 PM".to_date(format: "MM/DD/YYYY")
```
* * *
## [#](<#to-f>) to_f
Convert to float. Numbers are rounded up or down according to regular rounding rules.
```ruby
45.to_f #45.0
```
* * *
## [#](<#to-hex>) to_hex
Converts binary string to its hex representation.
* * *
## [#](<#to-i>) to_i
Convert to integer. Decimals are always rounded down.
```ruby
45.67.to_i #45
```
* * *
## [#](<#to-json>) to_json
Converts hash or array into JSON string.
```ruby
{"a" => "c d", "2" => "3"}.to_json #"{"a":"c d","2":"3"}"
```
* * *
## [#](<#to-phone>) to_phone
Convert string or number to a formatted phone number.
```ruby
5551234.to_phone # 555-1234
1235551234.to_phone(area_code: true) # (123) 555-1234
1235551234.to_phone(delimiter: " ") # 123 555 1234
1235551234.to_phone(country_code: 1) # +1-123-555-1234
```
* * *
## [#](<#to-param>) to_param
Returns a string representation for use as a URL query string.
```ruby
{name: 'Jake', age: '22'}.to_param #name=Jake&age=22
```
* * *
## [#](<#to-s>) to_s
Convert to string.
```ruby
45.67.to_s #"45.67"
```
* * *
## [#](<#to-state-code>) to_state_code
Convert state name to code.
```ruby
"California".to_state_code #CA
```
* * *
## [#](<#to-state-name>) to_state_name
Convert state code to name.
```ruby
"CA".to_state_name #"CALIFORNIA"
```
* * *
## [#](<#to-time>) to_time
Convert string or date to timestamp.
```ruby
"2014-11-21".to_time #2014-11-21 00:00:00 +0000
```
* * *
## [#](<#to-xml>) to_xml
Converts hash or array into XML string.
```ruby
{"name" => "Ken"}.to_xml(root: "user") # <user><name>Ken</name></user>
```
* * *
## [#](<#today>) today
Date today. Returns the date of the moment that the formula was executed, in Pacific time (UTC-8/UTC-7).
```ruby
today #2016-07-13
today + 2.days #2016-07-15
```
* * *
## [#](<#transliterate>) transliterate
Replaces non-ASCII characters with an ASCII approximation, or if none exists, a replacement character which defaults to '?'.
```ruby
'Chloé'.transliterate #Chloe
```
* * *
## [#](<#upcase>) upcase
Convert string to upper case.
```ruby
"Convert to UPCASE".upcase #"CONVERT TO UPCASE"
```
* * *
## [#](<#uniq>) uniq
Return unique items in an array.
```ruby
[1.0, 1.5, 1.0].uniq #[1.0, 1.5]
```
* * *
## [#](<#unpack>) unpack
Decodes a string into an array.
See [unpack (opens new window)](<https://apidock.com/ruby/String/unpack>) method definition.
* * *
## [#](<#utc>) utc
Convert Time to UTC timezone.
See [utc (opens new window)](<http://ruby-doc.org/core-2.2.0/Time.html#method-c-utc>) method definition.
* * *
## [#](<#uuid>) uuid
Creates a UUID. Useful when sending strings that are unique in a request.
```ruby
workato.uuid #c52d735a-aee4-4d44-ba1e-bcfa3734f553 => "eyJhbGciO..."
```
* * *
## [#](<#wday>) wday
Returns day of the week where 1 is Monday.
* * *
## [#](<#where>) where
Filter array by given condition.
* * *
## [#](<#while>) while
While loop statement.
See [ruby_loops (opens new window)](<https://www.tutorialspoint.com/ruby/ruby_loops.htm>) method definition.
* * *
## [#](<#wrap>) wrap
Wraps its argument in an array unless it is already an array
The wrap method is often used in the execute block of the while loop statement.
```ruby
execute: lambda do |connection, input|
{
accounts: Array.wrap(get("/accounts", input)["records"])
}
end
```
This ensures that the `accounts` variable is always an array in spite of whatever return. At Workato, we often use this to guard against unexpected returns from the various APIs we work with.
See [wrap (opens new window)](<https://apidock.com/rails/Array/wrap/class>) method definition.
* * *
## [#](<#yday>) yday
Returns day of the year.
```ruby
"2016-07-19 10:45:30".to_time.yday #201
```
* * *
## [#](<#yweek>) yweek
Returns week of the year.
```ruby
"2016-07-19 10:45:30".to_time.yweek #29
```
* * *
## [#](<#zip>) zip
Used as a method called by arrays. Converts any arguments to arrays, then merges elements of self with corresponding elements from each argument.
See [zip (opens new window)](<https://apidock.com/ruby/Array/zip>) method definition.
```
### references/sdk-reference__streams.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/streams.html
> **Fetched**: 2026-01-18T02:50:36.401590
---
# [#](<#sdk-reference-streams>) SDK Reference - `streams`
This section enumerates all the possible keys to define a streaming callback that enables you to create file stream producing actions. [Learn more about file streaming.](</developing-connectors/sdk/guides/building-actions/streaming.html>)
Quick overview
The `streams` key must be used in conjunction with an action or trigger. It enables you to download large amounts of data such as a CSV file or video in chunks from a compatible API. This allows you to build actions that can connect to Workato's ecosystem of file storage providers such as Workato Files, Google Cloud Storage, S3 and many more.
## [#](<#structure>) Structure
```ruby
streams: {
[Unique_stream_name]: lambda do |input, starting_byte_range, ending_byte_range, byte_size|
Array
end,
[Another_unique_stream_name]: lambda do |input, starting_byte_range, ending_byte_range, byte_size|
Array
end,
},
```
* * *
Attribute | Description
---|---
Key | `[Unique_stream_name]`
Type | lambda function
Description | This lambda function can be invoked by any streaming action using the `workato.stream.out` callback.
Possible Arguments | `input` \- Hash representing user given inputs defined in `workato.stream.out`
`starting_byte_range` \- Integer representing the requested start byte range for this particular chunk.
`ending_byte_range`\- Integer representing the requested ending byte range for this particular chunk.
`byte_size`\- Integer representing the exact amount of bytes for this particular chunk.
Expected Output | Array of size 2. The first index represents the actual bytes for this particular chunk. The second index is a boolean value that tells the Workato framework whether this is the last chunk in the file.
Creating a file stream
File streams on Workato are made by leveraging the common [HTTP RFC standard for `Range` headers (opens new window)](<https://datatracker.ietf.org/doc/html/rfc7233>). Below we have a simple download file action with file streaming.
```ruby
actions: {
download_file: {
title: "Download file",
input_fields: lambda do
[
{
name: "file_id",
label: "File ID"
}
]
end,
execute: lambda do
{
file_contents: workato.stream.out("download_file", { file_id: file_id })
}
end,
output_fields: lambda do
[
{
name: "file_contents"
}
]
end
}
}
```
The stream `download_file` defined in the `workato.stream.out` method is responsible for holding the code that retrieves a specific range of bytes requested by the platform - which will be sent over to a stream consumer to be uploaded into a downstream destination.
As such, the arguments passed to this callback provide you clear inputs that you can use in your HTTP requests to retrieve this range of bytes.
The output of the stream lambda is an array which expects the byte string in the first index and in the second index, a boolean value which should be true if this is the end of the file.
```ruby
streams: {
download_file: lambda do |input, starting_byte_range, ending_byte_range, byte_size|
# Example starting_byte_range = 0
# Example ending_byte_range = 10485759
# Example byte_size = 10485760 (10MB)
# input passed from action can be assumed to be a friendly URL
chunk = get("/#{input['file_id']}/download").
headers("Range": "bytes=#{starting_byte_range}-#{ending_byte_range}").
response_format_raw
# if the chunk.size is smaller than the requested byte_size,
# then we know we are at the end of the file.
[chunk, chunk.size < byte_size]
end
}
```
Take note that the `download_file` lambda is only executed when the datapill for `file_contents` is mapped to a downstream action.
```
### references/sdk-reference__test.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/test.html
> **Fetched**: 2026-01-18T02:50:37.518282
---
# [#](<#sdk-reference-test>) SDK Reference - `test`
This section enumerates all the possible keys available when testing your connection.
Quick Overview
The `test` lambda tells your connector how to check if the connection is valid. After it has taken the input from the user and executed the `authorization` block, this test verifies that the credentials supplied are valid via a simple HTTP request.
The `test` lambda is executed when a connection a user first clicks connect. The only exception is for OAuth2 authorization code grant connections, where the connection is marked as connected when Workato has successfully exchanged the authorization code for access tokens.
The `test` lambda is also executed for all types of connections upon recipe start and job rerun to ensure that the connection's credentials are still valid.
## [#](<#structure>) Structure
```ruby
test: lambda do |connection|
# see test: documentation for more information
end
```
* * *
## [#](<#test>) `test`
Attribute | Description
---|---
Key | `test`
Type | lambda function
Required | True
Description | A simple HTTP request that can verify that we have established a successful connection. This connection is marked as "Successful" when the HTTP response is 2XX.
Example - test:
APIs normally provide an endpoint that returns information about the authenticated user. These endpoints are ideal for your connector to verify that connection has been established.
```ruby
test: lambda do |connection|
get('/api/v5/me')
end
```
In cases where this is not available, you may also choose to use simple requests. Normally this could be to search for results in the target API. These requests should also allow you to verify that the connection is valid.
```ruby
test: lambda do |connection|
get("https://person.clearbit.com/v1/people/email/[[email protected]](</cdn-cgi/l/email-protection>)")
end
```
```
### references/sdk-reference__custom-action.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/custom-action.html
> **Fetched**: 2026-01-18T02:50:28.091263
---
# [#](<#sdk-reference-custom-action>) SDK Reference - `custom_action`
This section enumerates all the possible keys to define a custom action.
Quick Overview
The `custom_action` key allows you to quickly define custom actions to unblock users of your connector when no standard action is available to them. Keep in mind that these actions require users to understand certain API concepts like how to find the relevant API endpoints and payload schema.
## [#](<#structure>) Structure
```ruby
custom_action: Boolean,
custom_action_help: {
learn_more_url: String,
learn_more_text: String,
body: String
}
```
* * *
## [#](<#custom-action>) `custom_action`
Attribute | Description
---|---
Key | `custom_action`
Type | Boolean
Required | Optional. Defaults to false where no custom action is added to your connector. Set to true to add custom actions as an option for your users.
Description | This adds a custom action to your connector.
Expected Output | `Boolean`
i.e. `true`
UI reference | 
* * *
## [#](<#custom-action-help>) `custom_action_help`
Attribute | Description
---|---
Key | `custom_action_help`
Type | Hash
Required | Optional. If custom_action is `true`, then this hash allows you to customize the help text in your action.
Description | Allows you to configure the help body, help button url and label.
Expected Output | `Hash` See below for more information
UI reference | 
TIP
Custom action help is important to guide users to the proper websites to collect information such as API documentation.
* * *
## [#](<#learn-more-url>) `learn_more_url`
Attribute | Description
---|---
Key | `learn_more_url`
Type | String
Required | Optional.
Description | Defines the URL to send users when they click on the help link in the custom action.
Expected Output | `'www.api-reference.com'`
* * *
## [#](<#learn-more-text>) `learn_more_text`
Attribute | Description
---|---
Key | `learn_more_text`
Type | String
Required | Optional.
Description | The label for the hyperlink text in the help.
Expected Output | `'API documentation'`
* * *
## [#](<#body>) `body`
Attribute | Description
---|---
Key | `body`
Type | String
Required | Optional.
Description | The main help text body that appears above the learn more button. This body is HTML compatible.
Expected Output | `'<p>Build your own Chargebee action with a HTTP request. <b>The request will be authorized with your Chargebee Hana connection.</b></p>`
```
### references/sdk-reference__whitelist-removal.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/sdk-reference/whitelist-removal.html
> **Fetched**: 2026-01-18T02:50:39.889139
---
# [#](<#removal-of-ruby-whitelist-for-sdk>) Removal of Ruby whitelist for SDK
Following the migration of custom connector code execution to **isolated containers** , **Ruby whitelisting** is removed from the connector SDK. This change significantly expands the range of capabilities SDK developers can use within the platform. Developers can now leverage the **full functionality of Ruby 2.7** , including built-in libraries and Ruby gems available in the SDK container.
## [#](<#key-capabilities>) Key capabilities
With the removal of Ruby whitelisting, developers can now access the full functionality of Ruby 2.7, including built-in libraries and Ruby gems available in the SDK container.
* **Access to Ruby 2.7 standard methods**
Developers now have access to the full range of Ruby 2.7 standard methods. Developers can also use Ruby’s `require` method to import built-in libraries, such as JSON, CSV, socket, and others.
* **Pre-installed Ruby Gems**
Developers can now directly use a selection of pre-installed Ruby gems without restrictions:
* `activesupport` (5.2.8.1)
* `aws-sigv4` (1.2.4)
* `charlock_holmes` (0.7.7)
* `concurrent-ruby` (1.2.3)
* `gyoku` (1.3.1)
* `i18n` (0.9.5)
* `jwt` (2.1.0)
* `loofah` (2.21.3)
* `mime-types` (3.5.2)
* `nokogiri` (1.15.6)
* `rails-html-sanitizer` (1.4.4)
* `rest-client` (2.1.0)
* `ruby_rncryptor` (3.0.2)
* **TCP sockets**
Developers can now leverage TCP sockets for low-level TCP connections. [Learn more (opens new window)](<https://ruby-doc.org/stdlib-2.7.0/libdoc/socket/rdoc/TCPSocket.html>).
* Example use case: Implement MQTP protocol over UDP or WebSocket connections.
* **Classes and modules**
Developers can now define classes and modules, improving code reusability, organization, and maintainability.
* **Dynamic code execution**
Using the `eval` method, developers can now dynamically load and execute code. Code can be generated on the fly based on runtime data and executed immediately.
* **Multi-threaded and concurrent code**
Developers can now write multi-threaded and concurrent code.
## [#](<#example-connector-ideas>) Example connector ideas
* **E-commerce data scraper**
A connector that uses `nokogiri` to scrape product data from various e-commerce websites, transforms the data using `gyoku`, and uploads it to a central database for analysis.
* **Secure API Gateway**
A connector that uses `jwt` for secure API authentication and `rest-client` to interact with multiple third-party APIs, aggregating data and providing a unified interface.
* **Amazon S3 file manager**
A connector that uses `aws-sigv4` to securely upload and download files from Amazon S3, with MIME type handling using `mime-types` to ensure correct file processing.
* **HTML sanitization**
A connector that uses `loofah` and `rails-html-sanitizer` to sanitize HTML content, removing potentially harmful elements and ensuring data integrity.
* **Real-time data processor**
A connector that uses `concurrent-ruby` to process multiple data streams in parallel, such as Internet of Things sensor data, performing real-time analysis and actions.
* **Concurrent processing**
A connector that uses `concurrent-ruby` to handle concurrent tasks, improving the performance and responsiveness of connectors.
* **JWT authentication**
A connector that uses the `jwt` gem to create and verify JSON web tokens for secure API authentication.
* **XML and HTML data handling**
A connector that uses `nokogiri` and `gyoku` for parsing, transforming, and generating XML and HTML data. This can be useful for integrating with systems that use XML-based APIs or for web scraping tasks.
```
### references/guides.md
```markdown
# Workato SDK Documentation
> **Source**: https://docs.workato.com/en/developing-connectors/sdk/guides.html
> **Fetched**: 2026-01-18T02:49:20.360405
---
# [#](<#connector-how-to-guides>) Connector how-to guides
The guides in this section help you cover various parts of building a connector from authentication to building actions or triggers. Take a look at the examples to get a sensing of how you can build your connector! Here are some basics to get you started:
## [#](<#the-basics>) The basics
In Workato, we allow you to build custom connectors on our SDK using ruby (a coding language). Some basic coding knowledge in any language is recommended but we believe our SDK (Software Development Kit) has been built such that users at any level will be able to build custom connectors. The custom connectors you build can be used in any number of your recipes and you'll also able to share them with your coworkers, friends, or even the community at large.
Through out the whole process, you'll be able to build, test, and push out your custom connector directly from Workato's platform. This means working directly from the browser you have open right now and never having to install anything onto your computer. Pretty neat right?
Connector source code which you write on the SDK platform will be hosted in Workato's servers and is executed whenever a recipe using that connector is triggered. To find out more about the features of the Connector SDK console, check out our [Platform Quick Start](</developing-connectors/sdk/quickstart/quickstart.html>).
## [#](<#connector-definition-overview>) Connector definition overview
A custom connector on Workato always starts off with curly braces that encapsulates all code (Curly braces look like this `{}`). Inside the curly braces, each connector has numerous root keys that are responsible for different aspects of the connector. For example, the code `connection: { ... }` is referred to as the `connection` key. To find out more information about Connector definitions, check out our [SDK reference](</developing-connectors/sdk/sdk-reference.html>)
Take note that these key names are strictly defined and must be spelled exactly. Our framework uses these keys to know where to refer when looking to perform authorizations or execute any triggers or actions. Inside each object, there will be further nested keys that allow you to declare input fields for connections, actions, and triggers which we will cover later on.
## [#](<#sdk-cheat-sheet>) SDK cheat sheet
Read and download our [SDK cheat sheet (opens new window)](<https://public-workato-files.s3.us-east-2.amazonaws.com/Uploads/workato_connector_sdk_cheat_sheet.pdf>) to get started with the connector SDK quickly.
```