---
title: "Get service configuration"
method: GET
path: "/v1/projects/{project_id}/services/{id}/config"
tags: ["Service"]
---

# Get service configuration

`GET /v1/projects/{project_id}/services/{id}/config`

## Request

- Base URL: `https://api.telerivet.com`
- URL: `https://api.telerivet.com/v1/projects/{project_id}/services/{id}/config`
- Auth: one of:
  - HTTP basic
  - OAuth 2 (authorization code, authorization URL `https://telerivet.com/oauth/authorize`, token URL `https://api.telerivet.com/oauth/token`)

Gets configuration specific to the type of automated service.

 Only certain types of services provide their configuration via the API. See Service Configuration Reference or the machine-readable [OpenAPI specification](https://api.telerivet.com/openapi.json) for available configuration options.

**Response Schema:** The response object structure depends on the service's `service_type`:
- `incoming_message_actions`: Returns `ServiceConfigIncomingMessageActions`
- `contact_actions`: Returns `ServiceConfigContactActions`
- `message_actions`: Returns `ServiceConfigMessageActions`
- `project_actions`: Returns `ServiceConfigProjectActions`
- `message_status_actions`: Returns `ServiceConfigMessageStatusActions`
- `voice_actions`: Returns `ServiceConfigVoiceActions`
- `ussd_actions`: Returns `ServiceConfigUssdActions`
- `data_row_actions`: Returns `ServiceConfigDataRowActions`
- `incoming_message_webhook`: Returns `ServiceConfigIncomingMessageWebhook`
- `optin_optout`: Returns `ServiceConfigOptinOptout`
- `keyword_auto_reply`: Returns `ServiceConfigKeywordAutoReply`
- `messaging_poll`: Returns `ServiceConfigMessagingPoll`
- `voice_poll`: Returns `ServiceConfigVoicePoll`
- `scheduled_actions`: Returns `ServiceConfigScheduledActions`
- `auto_reply`: Returns `ServiceConfigAutoReply`
- `call_auto_reply`: Returns `ServiceConfigCallAutoReply`
- `*_script` types: Returns `ServiceConfigScript` (code)
- `opt_out_page`: Returns `ServiceConfigOptOutPage`
- `button_page`: Returns `ServiceConfigButtonPage`
- `custom_template_instance`: Returns `ServiceConfigCustomTemplateInstance`

See `x-service-types` in the API info section for complete schema details.

**Cloud Script API Reference:** For comprehensive documentation of the JavaScript functions and objects available within Cloud Script services, see the TypeScript declarations at https://api.telerivet.com/script.d.ts.

## Path parameters

- `project_id` string, required
- `id` string, required

## Response `200`

Service configuration object (structure depends on service_type)

- union
  - ServiceConfigIncomingMessageActions: Configuration for `incoming_message_actions` service type.
    - `actions` MessageAction[]: Array of actions to execute. Each action is an object with a `type` property and additional properties depending on the action type. See <a href="/api/rules_engine#actions">Action Reference</a> for documentation of available action types.
      - union: An action available for `incoming_message_actions` and `message_actions` service types.
        - object: Sends a text reply to the sender. Optionally, the reply can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
          - `type` 'reply', required: Action type identifier
          - `body` MessageBodyWithVariants, required
            - `content` string: Text content of the message.
            - `media` object[]: Array of media attachments.
              - …
            - `route_params` object: Route-specific parameters for the message. See <a href="#route_params">Route-Specific Parameters</a>.
            - `track_clicks` boolean: Whether to shorten links and track link clicks in this message.
            - `short_link_params` object: Parameters for short links when track_clicks is enabled.
              - …
            - `variants` object[]: Allows sending different message bodies depending on the route that sends the message, or the contact that the message is sent to. Each variant has conditions and its own message body. When each message is sent, the first variant whose conditions match is used instead of the default message body; if no variant matches, the default message body is used. A variant replaces the entire message body: content, media, route_params, track_clicks and short_link_params that are not specified in the variant are empty, not inherited from the default message body. Conditions are evaluated when the message is sent by a particular basic route, and can use the same variables as outgoing message content: contact variables such as [[contact.name]] and [[contact.vars.\*]], [[to_number]], [[time]], [[project.\*]], and variables of the basic route sending the message: [[phone.type]] (e.g. whatsapp), [[phone.id]], [[phone.vars.\*]], and [[phone.supports_quick_replies]], [[phone.supports_link_button]], [[phone.supports_native_attachments]] (1 if the route supports the feature, otherwise 0). Variables may include filters, e.g. [[contact.vars.language|default:"en"]]. For all available variables, see the <a href='https://telerivet.com/api/rest#variables'>Variable Reference</a>. In services and polls, conditions can't use variables that are only available in the service, such as [[content]] or [[state.\*]] (to use them, first store the value in a contact field, e.g. with a set_contact_var action, and then use [[contact.vars.\*]]). For A/B testing, a variant can have a random split (split_percent) so that it is only used for a random percentage of recipients, e.g. a single variant with split_percent 50 is used for about half of the recipients, and the default message body for the others. A random split can be combined with other conditions to run separate A/B tests for different routes or contacts. Since the first matching variant is used, list more specific variants before more general ones. For example, a variant with a condition `[[contact.vars.language]] is 'fr'` and split_percent 50 must be listed before a variant with only the condition `[[contact.vars.language]] is 'fr'`. Up to 10 variants are supported, each with up to 5 conditions.
              - …
          - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
          - `label_names` string[]: Array of label names to apply to the sent message.
          - `schedule` object: Schedule to send the message at a later time.
          - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
          - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
        - object: Sends a text message to any phone number. Optionally, the message can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
          - `type` 'send_text', required: Action type identifier
          - `body` MessageBodyWithVariants, required
            - `content` string: Text content of the message.
            - `media` object[]: Array of media attachments.
              - …
            - `route_params` object: Route-specific parameters for the message. See <a href="#route_params">Route-Specific Parameters</a>.
            - `track_clicks` boolean: Whether to shorten links and track link clicks in this message.
            - `short_link_params` object: Parameters for short links when track_clicks is enabled.
              - …
            - `variants` object[]: Allows sending different message bodies depending on the route that sends the message, or the contact that the message is sent to. Each variant has conditions and its own message body. When each message is sent, the first variant whose conditions match is used instead of the default message body; if no variant matches, the default message body is used. A variant replaces the entire message body: content, media, route_params, track_clicks and short_link_params that are not specified in the variant are empty, not inherited from the default message body. Conditions are evaluated when the message is sent by a particular basic route, and can use the same variables as outgoing message content: contact variables such as [[contact.name]] and [[contact.vars.\*]], [[to_number]], [[time]], [[project.\*]], and variables of the basic route sending the message: [[phone.type]] (e.g. whatsapp), [[phone.id]], [[phone.vars.\*]], and [[phone.supports_quick_replies]], [[phone.supports_link_button]], [[phone.supports_native_attachments]] (1 if the route supports the feature, otherwise 0). Variables may include filters, e.g. [[contact.vars.language|default:"en"]]. For all available variables, see the <a href='https://telerivet.com/api/rest#variables'>Variable Reference</a>. In services and polls, conditions can't use variables that are only available in the service, such as [[content]] or [[state.\*]] (to use them, first store the value in a contact field, e.g. with a set_contact_var action, and then use [[contact.vars.\*]]). For A/B testing, a variant can have a random split (split_percent) so that it is only used for a random percentage of recipients, e.g. a single variant with split_percent 50 is used for about half of the recipients, and the default message body for the others. A random split can be combined with other conditions to run separate A/B tests for different routes or contacts. Since the first matching variant is used, list more specific variants before more general ones. For example, a variant with a condition `[[contact.vars.language]] is 'fr'` and split_percent 50 must be listed before a variant with only the condition `[[contact.vars.language]] is 'fr'`. Up to 10 variants are supported, each with up to 5 conditions.
              - …
          - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
          - `label_names` string[]: Array of label names to apply to the sent message.
          - `schedule` object: Schedule to send the message at a later time.
          - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
          - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - `to_number` string, required: Phone number to send the message to.
        - object: Sends a SMS message to a group defined on your Contacts page. Optionally, you can exclude the message sender from receiving the message (common when implementing a group chat system).
          - `type` 'send_text_to_group', required: Action type identifier
          - `body` MessageBodyWithVariants, required
            - `content` string: Text content of the message.
            - `media` object[]: Array of media attachments.
              - …
            - `route_params` object: Route-specific parameters for the message. See <a href="#route_params">Route-Specific Parameters</a>.
            - `track_clicks` boolean: Whether to shorten links and track link clicks in this message.
            - `short_link_params` object: Parameters for short links when track_clicks is enabled.
              - …
            - `variants` object[]: Allows sending different message bodies depending on the route that sends the message, or the contact that the message is sent to. Each variant has conditions and its own message body. When each message is sent, the first variant whose conditions match is used instead of the default message body; if no variant matches, the default message body is used. A variant replaces the entire message body: content, media, route_params, track_clicks and short_link_params that are not specified in the variant are empty, not inherited from the default message body. Conditions are evaluated when the message is sent by a particular basic route, and can use the same variables as outgoing message content: contact variables such as [[contact.name]] and [[contact.vars.\*]], [[to_number]], [[time]], [[project.\*]], and variables of the basic route sending the message: [[phone.type]] (e.g. whatsapp), [[phone.id]], [[phone.vars.\*]], and [[phone.supports_quick_replies]], [[phone.supports_link_button]], [[phone.supports_native_attachments]] (1 if the route supports the feature, otherwise 0). Variables may include filters, e.g. [[contact.vars.language|default:"en"]]. For all available variables, see the <a href='https://telerivet.com/api/rest#variables'>Variable Reference</a>. In services and polls, conditions can't use variables that are only available in the service, such as [[content]] or [[state.\*]] (to use them, first store the value in a contact field, e.g. with a set_contact_var action, and then use [[contact.vars.\*]]). For A/B testing, a variant can have a random split (split_percent) so that it is only used for a random percentage of recipients, e.g. a single variant with split_percent 50 is used for about half of the recipients, and the default message body for the others. A random split can be combined with other conditions to run separate A/B tests for different routes or contacts. Since the first matching variant is used, list more specific variants before more general ones. For example, a variant with a condition `[[contact.vars.language]] is 'fr'` and split_percent 50 must be listed before a variant with only the condition `[[contact.vars.language]] is 'fr'`. Up to 10 variants are supported, each with up to 5 conditions.
              - …
          - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
          - `label_names` string[]: Array of label names to apply to the sent message.
          - `schedule` object: Schedule to send the message at a later time.
          - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
          - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - `group_name` string, required: Name of the group to send the message to.
          - `exclude_sender` boolean: If true, exclude the message sender from receiving the group message.
        - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
          - `type` 'add_contact_to_group', required: Action type identifier
          - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
        - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
          - `type` 'remove_contact_from_group', required: Action type identifier
          - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
        - object: Creates or retrieves a contact with a particular phone number, and sets that as the "current" contact for subsequent rules. This rule is often used to allow your organization's workers to register other people via SMS, and is typically combined with other rules to add the contact to a group and update their contact information.
          - `type` 'set_contact', required: Action type identifier
          - `phone_number` string, required: Phone number for the contact to use.
        - object: Updates the name of the current contact in Telerivet.
          - `type` 'set_contact_name', required: Action type identifier
          - `name` string, required: Name to assign to the contact.
        - object: Updates custom contact information for the current contact (for example, email address or birthdate). The rules editor lists the current variable names available for your project. You can also use a new variable name consisting of letters, numbers, and underscores.
          - `type` 'set_contact_var', required: Action type identifier
          - `variable` string, required: Name of the contact variable to set (without the contact.vars prefix).
          - `value` string: Value to assign to the variable.
        - object: Blocks the current contact.
          - `type` 'block_contact', required: Action type identifier
          - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
        - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
          - `type` 'send_email', required: Action type identifier
          - `to_email` string, required: Recipient email address.
          - `subject` string, required: Email subject line.
          - `body_text` string, required: Email body text.
          - `reply_to` string: Reply-to email address.
          - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
        - object: Sends airtime to the current contact if they are on a particular mobile network. Acts like a condition, and allows running other actions if the contact is on one of the supported networks. An 'else' condition can be added below this action to handle contacts that are not on the supported mobile networks.
          - `type` 'send_airtime', required: Action type identifier
          - `provider_id` string, required: ID of the airtime provider to use.
          - `products` object[], required: Array of product configurations for different mobile networks or countries.
            - `country` string, required: Two-letter country code (e.g., KE for Kenya).
            - `operator_id` string: ID of the mobile network operator (according to the airtime provider). Required if the provider supports multiple operators.
            - `product_id` string, required: ID of the airtime product to send (according to the airtime provider).
            - `amount` number: Amount of airtime to send. Required for variable-amount products.
          - `actions` Action[]: Array of actions to execute if the contact is on a supported mobile network.
            - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
              - …
          - `on_success` string: Name of subroutine to execute when the airtime transaction succeeds.
          - `on_failure` string: Name of subroutine to execute when the airtime transaction fails.
        - object: Adds a label to the current message. This makes it easy to segment certain types of messages on your Messages page.
          - `type` 'add_label_to_message', required: Action type identifier
          - `label_name` string, required: Name of the label to add to the message.
        - object: Adds a star to the current message. This makes it easy to segment important messages on your Messages page.
          - `type` 'star_message', required: Action type identifier
        - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
          - `type` 'set_variable', required: Action type identifier
          - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
          - `value` string, required: Value to assign to the variable.
          - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
          - `value2` string: Second operand for the arithmetic operation (required if op is specified).
        - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
          - `type` 'cancel_scheduled_messages', required: Action type identifier
        - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
          - `type` 'webhook', required: Action type identifier
          - `url` string, required: Webhook URL to receive the HTTP POST request.
          - `secret` string: Secret string passed as POST parameter for request verification.
          - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
            - `name` string, required: POST parameter name (max 100 characters).
            - `value` string, required: Parameter value. May contain [[variables]].
        - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
          - `type` 'log', required: Action type identifier
          - `value` string, required: Log message content.
        - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
          - `type` 'run_script', required: Action type identifier
          - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
        - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
          - `type` 'condition', required: Action type identifier
          - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
            - `type` string, required: Condition type. Values: <code>is</code>, <code>is_not</code>, <code>has_word</code>, <code>does_not_have_word</code>, <code>contains</code>, <code>does_not_contain</code>, <code>starts_with</code>, <code>does_not_start_with</code>, <code>ends_with</code>, <code>does_not_end_with</code>, <code>alpha_before</code>, <code>alpha_after</code>, <code>equals</code>, <code>does_not_equal</code>, <code>less_than</code>, <code>greater_than</code>, <code>less_or_equal</code>, <code>greater_or_equal</code>, <code>contact_is_in_group</code>, <code>contact_not_in_group</code>.
            - `variable` string, required: Variable to test, e.g. <code>[[word1]]</code>, <code>[[contact.name]]</code>. Not required for <code>contact_is_in_group</code> and <code>contact_not_in_group</code> conditions.
            - `value` string, required: Value to compare against (or group name for group membership conditions).
          - `actions` Action[], required: Array of actions to execute if the conditions match.
            - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
              - …
          - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
          - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
        - object: Triggers another service for the current contact.
          - `type` 'trigger_contact_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
          - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
          - `schedule` object: Schedule for when to trigger the service. If not specified, triggers the service immediately.
        - object: Triggers another service for the current message.
          - `type` 'trigger_message_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
          - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
        - object: Triggers another service for the current project.
          - `type` 'trigger_project_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
        - object: Stops processing rules for this message (for this service only).
          - `type` 'stop', required: Action type identifier
        - object: Copies the current incoming message to another project within the same organization. This is useful for routing messages to different projects based on message content or contact information, while keeping the original message in the current project.
          - `type` 'copy_message_to_project', required: Action type identifier
          - `project_id` string, required: ID of the project to copy the message to. Must be a project within the same organization.
        - object: Updates a custom variable for the current message. When triggered from a service that has a response data table (such as a poll service or custom actions with response handlers), custom message variables set via this action are automatically copied as custom variables on the corresponding response data table row. This is the recommended way to store derived or computed values in the response data table.
          - `type` 'set_message_var', required: Action type identifier
          - `variable` string, required: Name of the message variable to set (without the vars prefix).
          - `value` string: Value to assign to the variable.
        - object: Waits for a response from the current contact, then processes the response using another set of actions or conditions. Useful for back-and-forth conversations or data collection that requires the contact to send multiple messages.
          - `type` 'wait_response', required: Action type identifier
          - `state_id` string, required: ID of the response handler to process the contact's response.
          - `timeout` object: Schedule for response timeout.
        - object: Sends a USSD request from your Android phone to your mobile network. On some mobile networks, USSD requests can be used to check your airtime balance, transfer airtime to other phone numbers, and more. Note that this requires a compatible Android phone running the Telerivet Gateway app. Also, Telerivet cannot automatically invoke USSD requests that return menus or prompts.
          - `type` 'send_ussd', required: Action type identifier
          - `mmi_code` string, required: USSD/MMI code to send (e.g. *123#).
          - `route_id` string: ID of the route to send the USSD request from. If not specified, uses the default route.
        - object: Triggers a set of actions which can be reused multiple times in the same service.
          - `type` 'run_subroutine', required: Action type identifier
          - `name` string, required: Name of the subroutine to run.
        - object: Sends a voice call to the current contact using a specified IVR service.
          - `type` 'call_contact', required: Action type identifier
          - `service_id` string, required: ID of the voice/IVR service to use for the call.
          - `route_id` string: ID of the route to use for the call. If not specified, uses the default route.
          - `schedule` object: Schedule for when to make the call. If not specified, calls immediately.
        - object: Pushes the message to a Zendesk support inbox, in a ticket associated with the current contact. Zendesk agents can reply directly to the Zendesk ticket to send a reply to the contact.
          - `type` 'push_to_zendesk', required: Action type identifier
          - `subdomain` string, required: Zendesk subdomain (e.g., "example" for example.zendesk.com).
          - `subject` string, required: Subject line for the Zendesk ticket.
          - `content` string, required: Content of the Zendesk ticket.
        - object: Pushes the message to a HubSpot Help Desk inbox, in a conversation associated with the current contact. HubSpot agents can reply directly to send a reply to the contact.
          - `type` 'push_to_hubspot', required: Action type identifier
          - `integration_id` string, required: ID of the HubSpot channel integration config.
          - `content` string: Content of the message pushed to HubSpot.
    - `subroutines` object[]: Array of subroutine definitions. Subroutines are reusable sets of actions that can be called from the main actions or other subroutines.
      - `name` string, required: Unique name for the subroutine (max 32 characters).
      - `context` string: Context type for the subroutine. If not specified, defaults to the service's context.
      - `actions` Action[], required: Array of actions to execute when the subroutine is called. Available actions depend on the subroutine's context.
        - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
          - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'add_contact_to_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Adds a label to the current message. This makes it easy to segment certain types of messages on your Messages page.
            - `type` 'add_label_to_message', required: Action type identifier
            - `label_name` string, required: Name of the label to add to the message.
          - object: Blocks the current contact.
            - `type` 'block_contact', required: Action type identifier
            - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
          - object: Sends a voice call to the current contact using a specified IVR service.
            - `type` 'call_contact', required: Action type identifier
            - `service_id` string, required: ID of the voice/IVR service to use for the call.
            - `route_id` string: ID of the route to use for the call. If not specified, uses the default route.
            - `schedule` object: Schedule for when to make the call. If not specified, calls immediately.
          - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
            - `type` 'cancel_scheduled_messages', required: Action type identifier
          - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
            - `type` 'condition', required: Action type identifier
            - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
              - …
            - `actions` Action[], required: Array of actions to execute if the conditions match.
            - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
            - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
          - object: Copies the current incoming message to another project within the same organization. This is useful for routing messages to different projects based on message content or contact information, while keeping the original message in the current project.
            - `type` 'copy_message_to_project', required: Action type identifier
            - `project_id` string, required: ID of the project to copy the message to. Must be a project within the same organization.
          - object: Ends the current USSD session.
            - `type` 'end_session', required: Action type identifier
          - object: Within a poll service, skips to the end of the survey.
            - `type` 'end_survey', required: Action type identifier
          - object: Forwards the incoming call to another phone number.
            - `type` 'forward_call', required: Action type identifier
            - `phone_number` string, required: Phone number to forward the call to.
          - object: Hangs up the phone call.
            - `type` 'hangup', required: Action type identifier
          - object: Within a poll service, ignores the current message.
            - `type` 'ignore_message', required: Action type identifier
          - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
            - `type` 'log', required: Action type identifier
            - `value` string, required: Log message content.
          - object: Plays an audio file in WAV or MP3 format in the voice call, which may be uploaded, linked, or recorded via the Telerivet web app. Alternatively, can use text-to-speech to speak a message.
            - `type` 'play_audio', required: Action type identifier
            - `mode` 'file' | 'tts', required: Audio source mode.
            - `audio_url` string: URL of the audio file to play (WAV or MP3). Required when mode is "file".
            - `audio_title` string: Title for the audio file displayed in the web app (not played to the caller). Used when mode is "file".
            - `text` string: Text to speak using text-to-speech. Required when mode is "tts". If mode is "file", the text is not used in the actual call but is displayed as the transcript of the file within the web app.
            - `language` string: Language code for text-to-speech (e.g., "en-US"). Used when mode is "tts".
            - `voice` string: Voice for text-to-speech (e.g., "man", "woman"). Used when mode is "tts".
            - `repeat` boolean: If true, repeat the audio once after a short pause.
          - object: Pushes the message to a HubSpot Help Desk inbox, in a conversation associated with the current contact. HubSpot agents can reply directly to send a reply to the contact.
            - `type` 'push_to_hubspot', required: Action type identifier
            - `integration_id` string, required: ID of the HubSpot channel integration config.
            - `content` string: Content of the message pushed to HubSpot.
          - object: Pushes the message to a Zendesk support inbox, in a ticket associated with the current contact. Zendesk agents can reply directly to the Zendesk ticket to send a reply to the contact.
            - `type` 'push_to_zendesk', required: Action type identifier
            - `subdomain` string, required: Zendesk subdomain (e.g., "example" for example.zendesk.com).
            - `subject` string, required: Subject line for the Zendesk ticket.
            - `content` string, required: Content of the Zendesk ticket.
          - object: Records an audio response from the caller, saves the recording URL as a custom variable on the message, then triggers the associated response handler.
            - `type` 'record_audio', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the recording is received (e.g., "recording"). Also used as the name of the variable where the recording URL will be stored (e.g. [[vars.recording]]).
          - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'remove_contact_from_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Within a poll service, repeats the current question again.
            - `type` 'repeat_question', required: Action type identifier
          - object: Sends a text reply to the sender. Optionally, the reply can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'reply', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a text reply to the sender (simple version without labels, schedule, or route configuration).
            - `type` 'reply_simple', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `schedule` object: Schedule to send the message at a later time.
          - object: Within a service triggered when a message status changes, will automatically resend the current message via the same route or a different route.
            - `type` 'resend_message', required: Action type identifier
            - `route_id` string: ID of the route to resend the message from. If not specified, uses the original route.
            - `schedule` object: Schedule for when to resend the message. If not specified, resends immediately.
          - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
            - `type` 'run_script', required: Action type identifier
            - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
          - object: Triggers a set of actions which can be reused multiple times in the same service.
            - `type` 'run_subroutine', required: Action type identifier
            - `name` string, required: Name of the subroutine to run.
          - object: Sends airtime to the current contact if they are on a particular mobile network. Acts like a condition, and allows running other actions if the contact is on one of the supported networks. An 'else' condition can be added below this action to handle contacts that are not on the supported mobile networks.
            - `type` 'send_airtime', required: Action type identifier
            - `provider_id` string, required: ID of the airtime provider to use.
            - `products` object[], required: Array of product configurations for different mobile networks or countries.
              - …
            - `actions` Action[]: Array of actions to execute if the contact is on a supported mobile network.
            - `on_success` string: Name of subroutine to execute when the airtime transaction succeeds.
            - `on_failure` string: Name of subroutine to execute when the airtime transaction fails.
          - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
            - `type` 'send_email', required: Action type identifier
            - `to_email` string, required: Recipient email address.
            - `subject` string, required: Email subject line.
            - `body_text` string, required: Email body text.
            - `reply_to` string: Reply-to email address.
            - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
          - object: Sends a text message to any phone number. Optionally, the message can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'send_text', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `to_number` string, required: Phone number to send the message to.
          - object: Sends a text message to the current contact.
            - `type` 'send_text_to_contact', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a SMS message to a group defined on your Contacts page. Optionally, you can exclude the message sender from receiving the message (common when implementing a group chat system).
            - `type` 'send_text_to_group', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `group_name` string, required: Name of the group to send the message to.
            - `exclude_sender` boolean: If true, exclude the message sender from receiving the group message.
          - object: Sends a USSD request from your Android phone to your mobile network. On some mobile networks, USSD requests can be used to check your airtime balance, transfer airtime to other phone numbers, and more. Note that this requires a compatible Android phone running the Telerivet Gateway app. Also, Telerivet cannot automatically invoke USSD requests that return menus or prompts.
            - `type` 'send_ussd', required: Action type identifier
            - `mmi_code` string, required: USSD/MMI code to send (e.g. *123#).
            - `route_id` string: ID of the route to send the USSD request from. If not specified, uses the default route.
          - object: Shows the specified text in the active USSD session. If this action is followed by a 'Wait for response' action, the text will be displayed as part of a USSD prompt.
            - `type` 'send_ussd_reply', required: Action type identifier
            - `text` string, required: Text to display in the USSD session.
          - object: Creates or retrieves a contact with a particular phone number, and sets that as the "current" contact for subsequent rules. This rule is often used to allow your organization's workers to register other people via SMS, and is typically combined with other rules to add the contact to a group and update their contact information.
            - `type` 'set_contact', required: Action type identifier
            - `phone_number` string, required: Phone number for the contact to use.
          - object: Updates the name of the current contact in Telerivet.
            - `type` 'set_contact_name', required: Action type identifier
            - `name` string, required: Name to assign to the contact.
          - object: Updates custom contact information for the current contact (for example, email address or birthdate). The rules editor lists the current variable names available for your project. You can also use a new variable name consisting of letters, numbers, and underscores.
            - `type` 'set_contact_var', required: Action type identifier
            - `variable` string, required: Name of the contact variable to set (without the contact.vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Updates a custom variable for the current message. When triggered from a service that has a response data table (such as a poll service or custom actions with response handlers), custom message variables set via this action are automatically copied as custom variables on the corresponding response data table row. This is the recommended way to store derived or computed values in the response data table.
            - `type` 'set_message_var', required: Action type identifier
            - `variable` string, required: Name of the message variable to set (without the vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
            - `type` 'set_variable', required: Action type identifier
            - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
            - `value` string, required: Value to assign to the variable.
            - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
            - `value2` string: Second operand for the arithmetic operation (required if op is specified).
          - object: Within a poll service, skips to a question outside the normal order.
            - `type` 'skip_to_question', required: Action type identifier
            - `question_id` string, required: ID of the poll question to skip to.
          - object: Adds a star to the current message. This makes it easy to segment important messages on your Messages page.
            - `type` 'star_message', required: Action type identifier
          - object: Stops processing rules for this message (for this service only).
            - `type` 'stop', required: Action type identifier
          - object: Triggers another service for the current contact.
            - `type` 'trigger_contact_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
            - `schedule` object: Schedule for when to trigger the service. If not specified, triggers the service immediately.
          - object: Triggers another service for the current message.
            - `type` 'trigger_message_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
          - object: Triggers another service for the current project.
            - `type` 'trigger_project_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
          - object: Within a custom route, selects one or more basic routes that can be used to send the message.
            - `type` 'use_phone', required: Action type identifier
            - `phone_ids` string[], required: Array of basic route IDs that can be used to send the message
          - object: Waits for the caller to enter digits on the keypad, saves the input as a custom variable on the message, then triggers the associated response handler.
            - `type` 'wait_for_digits', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the response is received (e.g., "input"). Also used as the name of the variable where the entered digits will be stored (e.g. [[vars.input]].
            - `max_digits` number, required: Maximum number of digits to wait for.
            - `timeout` number: Number of seconds to wait after the last key press. Default: 10.
            - `submit_on_hash` boolean: If true, submit the input when the caller presses #.
          - object: Waits for the caller to press a single key on the keypad, saves the input as a custom variable on the message, then triggers the associated response handler.
            - `type` 'wait_for_key', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the key is pressed (e.g., "input"). Also used as the name of the variable where the pressed key will be stored (e.g. [[vars.input]]).
          - object: Waits for a response from the current contact, then processes the response using another set of actions or conditions. Useful for back-and-forth conversations or data collection that requires the contact to send multiple messages.
            - `type` 'wait_response', required: Action type identifier
            - `state_id` string, required: ID of the response handler to process the contact's response.
            - `timeout` object: Schedule for response timeout.
          - object: Prompts the user for input in the active USSD session, saves the response as a custom variable on the message, and triggers the associated response handler.
            - `type` 'wait_ussd_response', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the response is received (e.g., "input"). Also used as the name of the variable where the USSD response will be stored (e.g. [[vars.input]]).
          - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
            - `type` 'webhook', required: Action type identifier
            - `url` string, required: Webhook URL to receive the HTTP POST request.
            - `secret` string: Secret string passed as POST parameter for request verification.
            - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
              - …
    - `response_handlers` object[]: Array of response handler definitions. Response handlers are triggered when the service is waiting for input (e.g., after `wait_response` actions).
      - `state_id` string, required: Unique state identifier for this response handler. Must be a valid variable name and cannot be "initial".
      - `actions` MessageAction[], required: Array of actions to execute when a response is received in this state.
        - union: An action available for `incoming_message_actions` and `message_actions` service types.
          - object: Sends a text reply to the sender. Optionally, the reply can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'reply', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a text message to any phone number. Optionally, the message can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'send_text', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `to_number` string, required: Phone number to send the message to.
          - object: Sends a SMS message to a group defined on your Contacts page. Optionally, you can exclude the message sender from receiving the message (common when implementing a group chat system).
            - `type` 'send_text_to_group', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `group_name` string, required: Name of the group to send the message to.
            - `exclude_sender` boolean: If true, exclude the message sender from receiving the group message.
          - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'add_contact_to_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'remove_contact_from_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Creates or retrieves a contact with a particular phone number, and sets that as the "current" contact for subsequent rules. This rule is often used to allow your organization's workers to register other people via SMS, and is typically combined with other rules to add the contact to a group and update their contact information.
            - `type` 'set_contact', required: Action type identifier
            - `phone_number` string, required: Phone number for the contact to use.
          - object: Updates the name of the current contact in Telerivet.
            - `type` 'set_contact_name', required: Action type identifier
            - `name` string, required: Name to assign to the contact.
          - object: Updates custom contact information for the current contact (for example, email address or birthdate). The rules editor lists the current variable names available for your project. You can also use a new variable name consisting of letters, numbers, and underscores.
            - `type` 'set_contact_var', required: Action type identifier
            - `variable` string, required: Name of the contact variable to set (without the contact.vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Blocks the current contact.
            - `type` 'block_contact', required: Action type identifier
            - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
          - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
            - `type` 'send_email', required: Action type identifier
            - `to_email` string, required: Recipient email address.
            - `subject` string, required: Email subject line.
            - `body_text` string, required: Email body text.
            - `reply_to` string: Reply-to email address.
            - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
          - object: Sends airtime to the current contact if they are on a particular mobile network. Acts like a condition, and allows running other actions if the contact is on one of the supported networks. An 'else' condition can be added below this action to handle contacts that are not on the supported mobile networks.
            - `type` 'send_airtime', required: Action type identifier
            - `provider_id` string, required: ID of the airtime provider to use.
            - `products` object[], required: Array of product configurations for different mobile networks or countries.
              - …
            - `actions` Action[]: Array of actions to execute if the contact is on a supported mobile network.
              - …
            - `on_success` string: Name of subroutine to execute when the airtime transaction succeeds.
            - `on_failure` string: Name of subroutine to execute when the airtime transaction fails.
          - object: Adds a label to the current message. This makes it easy to segment certain types of messages on your Messages page.
            - `type` 'add_label_to_message', required: Action type identifier
            - `label_name` string, required: Name of the label to add to the message.
          - object: Adds a star to the current message. This makes it easy to segment important messages on your Messages page.
            - `type` 'star_message', required: Action type identifier
          - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
            - `type` 'set_variable', required: Action type identifier
            - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
            - `value` string, required: Value to assign to the variable.
            - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
            - `value2` string: Second operand for the arithmetic operation (required if op is specified).
          - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
            - `type` 'cancel_scheduled_messages', required: Action type identifier
          - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
            - `type` 'webhook', required: Action type identifier
            - `url` string, required: Webhook URL to receive the HTTP POST request.
            - `secret` string: Secret string passed as POST parameter for request verification.
            - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
              - …
          - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
            - `type` 'log', required: Action type identifier
            - `value` string, required: Log message content.
          - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
            - `type` 'run_script', required: Action type identifier
            - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
          - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
            - `type` 'condition', required: Action type identifier
            - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
              - …
            - `actions` Action[], required: Array of actions to execute if the conditions match.
              - …
            - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
            - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
          - object: Triggers another service for the current contact.
            - `type` 'trigger_contact_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
            - `schedule` object: Schedule for when to trigger the service. If not specified, triggers the service immediately.
          - object: Triggers another service for the current message.
            - `type` 'trigger_message_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
          - object: Triggers another service for the current project.
            - `type` 'trigger_project_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
          - object: Stops processing rules for this message (for this service only).
            - `type` 'stop', required: Action type identifier
          - object: Copies the current incoming message to another project within the same organization. This is useful for routing messages to different projects based on message content or contact information, while keeping the original message in the current project.
            - `type` 'copy_message_to_project', required: Action type identifier
            - `project_id` string, required: ID of the project to copy the message to. Must be a project within the same organization.
          - object: Updates a custom variable for the current message. When triggered from a service that has a response data table (such as a poll service or custom actions with response handlers), custom message variables set via this action are automatically copied as custom variables on the corresponding response data table row. This is the recommended way to store derived or computed values in the response data table.
            - `type` 'set_message_var', required: Action type identifier
            - `variable` string, required: Name of the message variable to set (without the vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Waits for a response from the current contact, then processes the response using another set of actions or conditions. Useful for back-and-forth conversations or data collection that requires the contact to send multiple messages.
            - `type` 'wait_response', required: Action type identifier
            - `state_id` string, required: ID of the response handler to process the contact's response.
            - `timeout` object: Schedule for response timeout.
          - object: Sends a USSD request from your Android phone to your mobile network. On some mobile networks, USSD requests can be used to check your airtime balance, transfer airtime to other phone numbers, and more. Note that this requires a compatible Android phone running the Telerivet Gateway app. Also, Telerivet cannot automatically invoke USSD requests that return menus or prompts.
            - `type` 'send_ussd', required: Action type identifier
            - `mmi_code` string, required: USSD/MMI code to send (e.g. *123#).
            - `route_id` string: ID of the route to send the USSD request from. If not specified, uses the default route.
          - object: Triggers a set of actions which can be reused multiple times in the same service.
            - `type` 'run_subroutine', required: Action type identifier
            - `name` string, required: Name of the subroutine to run.
          - object: Sends a voice call to the current contact using a specified IVR service.
            - `type` 'call_contact', required: Action type identifier
            - `service_id` string, required: ID of the voice/IVR service to use for the call.
            - `route_id` string: ID of the route to use for the call. If not specified, uses the default route.
            - `schedule` object: Schedule for when to make the call. If not specified, calls immediately.
          - object: Pushes the message to a Zendesk support inbox, in a ticket associated with the current contact. Zendesk agents can reply directly to the Zendesk ticket to send a reply to the contact.
            - `type` 'push_to_zendesk', required: Action type identifier
            - `subdomain` string, required: Zendesk subdomain (e.g., "example" for example.zendesk.com).
            - `subject` string, required: Subject line for the Zendesk ticket.
            - `content` string, required: Content of the Zendesk ticket.
          - object: Pushes the message to a HubSpot Help Desk inbox, in a conversation associated with the current contact. HubSpot agents can reply directly to send a reply to the contact.
            - `type` 'push_to_hubspot', required: Action type identifier
            - `integration_id` string, required: ID of the HubSpot channel integration config.
            - `content` string: Content of the message pushed to HubSpot.
  - ServiceConfigContactActions: Configuration for `contact_actions` service type.
    - `actions` ContactAction[]: Array of actions to execute. Each action is an object with a `type` property and additional properties depending on the action type. See <a href="/api/rules_engine#actions">Action Reference</a> for documentation of available action types.
      - union: An action available for `contact_actions` and `data_row_actions` service types.
        - object: Sends a text message to the current contact.
          - `type` 'send_text_to_contact', required: Action type identifier
          - `body` MessageBodyWithVariants, required
            - `content` string: Text content of the message.
            - `media` object[]: Array of media attachments.
              - …
            - `route_params` object: Route-specific parameters for the message. See <a href="#route_params">Route-Specific Parameters</a>.
            - `track_clicks` boolean: Whether to shorten links and track link clicks in this message.
            - `short_link_params` object: Parameters for short links when track_clicks is enabled.
              - …
            - `variants` object[]: Allows sending different message bodies depending on the route that sends the message, or the contact that the message is sent to. Each variant has conditions and its own message body. When each message is sent, the first variant whose conditions match is used instead of the default message body; if no variant matches, the default message body is used. A variant replaces the entire message body: content, media, route_params, track_clicks and short_link_params that are not specified in the variant are empty, not inherited from the default message body. Conditions are evaluated when the message is sent by a particular basic route, and can use the same variables as outgoing message content: contact variables such as [[contact.name]] and [[contact.vars.\*]], [[to_number]], [[time]], [[project.\*]], and variables of the basic route sending the message: [[phone.type]] (e.g. whatsapp), [[phone.id]], [[phone.vars.\*]], and [[phone.supports_quick_replies]], [[phone.supports_link_button]], [[phone.supports_native_attachments]] (1 if the route supports the feature, otherwise 0). Variables may include filters, e.g. [[contact.vars.language|default:"en"]]. For all available variables, see the <a href='https://telerivet.com/api/rest#variables'>Variable Reference</a>. In services and polls, conditions can't use variables that are only available in the service, such as [[content]] or [[state.\*]] (to use them, first store the value in a contact field, e.g. with a set_contact_var action, and then use [[contact.vars.\*]]). For A/B testing, a variant can have a random split (split_percent) so that it is only used for a random percentage of recipients, e.g. a single variant with split_percent 50 is used for about half of the recipients, and the default message body for the others. A random split can be combined with other conditions to run separate A/B tests for different routes or contacts. Since the first matching variant is used, list more specific variants before more general ones. For example, a variant with a condition `[[contact.vars.language]] is 'fr'` and split_percent 50 must be listed before a variant with only the condition `[[contact.vars.language]] is 'fr'`. Up to 10 variants are supported, each with up to 5 conditions.
              - …
          - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
          - `label_names` string[]: Array of label names to apply to the sent message.
          - `schedule` object: Schedule to send the message at a later time.
          - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
          - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
        - object: Sends a text message to any phone number. Optionally, the message can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
          - `type` 'send_text', required: Action type identifier
          - `body` MessageBodyWithVariants, required
            - `content` string: Text content of the message.
            - `media` object[]: Array of media attachments.
              - …
            - `route_params` object: Route-specific parameters for the message. See <a href="#route_params">Route-Specific Parameters</a>.
            - `track_clicks` boolean: Whether to shorten links and track link clicks in this message.
            - `short_link_params` object: Parameters for short links when track_clicks is enabled.
              - …
            - `variants` object[]: Allows sending different message bodies depending on the route that sends the message, or the contact that the message is sent to. Each variant has conditions and its own message body. When each message is sent, the first variant whose conditions match is used instead of the default message body; if no variant matches, the default message body is used. A variant replaces the entire message body: content, media, route_params, track_clicks and short_link_params that are not specified in the variant are empty, not inherited from the default message body. Conditions are evaluated when the message is sent by a particular basic route, and can use the same variables as outgoing message content: contact variables such as [[contact.name]] and [[contact.vars.\*]], [[to_number]], [[time]], [[project.\*]], and variables of the basic route sending the message: [[phone.type]] (e.g. whatsapp), [[phone.id]], [[phone.vars.\*]], and [[phone.supports_quick_replies]], [[phone.supports_link_button]], [[phone.supports_native_attachments]] (1 if the route supports the feature, otherwise 0). Variables may include filters, e.g. [[contact.vars.language|default:"en"]]. For all available variables, see the <a href='https://telerivet.com/api/rest#variables'>Variable Reference</a>. In services and polls, conditions can't use variables that are only available in the service, such as [[content]] or [[state.\*]] (to use them, first store the value in a contact field, e.g. with a set_contact_var action, and then use [[contact.vars.\*]]). For A/B testing, a variant can have a random split (split_percent) so that it is only used for a random percentage of recipients, e.g. a single variant with split_percent 50 is used for about half of the recipients, and the default message body for the others. A random split can be combined with other conditions to run separate A/B tests for different routes or contacts. Since the first matching variant is used, list more specific variants before more general ones. For example, a variant with a condition `[[contact.vars.language]] is 'fr'` and split_percent 50 must be listed before a variant with only the condition `[[contact.vars.language]] is 'fr'`. Up to 10 variants are supported, each with up to 5 conditions.
              - …
          - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
          - `label_names` string[]: Array of label names to apply to the sent message.
          - `schedule` object: Schedule to send the message at a later time.
          - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
          - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - `to_number` string, required: Phone number to send the message to.
        - object: Sends airtime to the current contact if they are on a particular mobile network. Acts like a condition, and allows running other actions if the contact is on one of the supported networks. An 'else' condition can be added below this action to handle contacts that are not on the supported mobile networks.
          - `type` 'send_airtime', required: Action type identifier
          - `provider_id` string, required: ID of the airtime provider to use.
          - `products` object[], required: Array of product configurations for different mobile networks or countries.
            - `country` string, required: Two-letter country code (e.g., KE for Kenya).
            - `operator_id` string: ID of the mobile network operator (according to the airtime provider). Required if the provider supports multiple operators.
            - `product_id` string, required: ID of the airtime product to send (according to the airtime provider).
            - `amount` number: Amount of airtime to send. Required for variable-amount products.
          - `actions` Action[]: Array of actions to execute if the contact is on a supported mobile network.
            - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
              - …
          - `on_success` string: Name of subroutine to execute when the airtime transaction succeeds.
          - `on_failure` string: Name of subroutine to execute when the airtime transaction fails.
        - object: Sends a voice call to the current contact using a specified IVR service.
          - `type` 'call_contact', required: Action type identifier
          - `service_id` string, required: ID of the voice/IVR service to use for the call.
          - `route_id` string: ID of the route to use for the call. If not specified, uses the default route.
          - `schedule` object: Schedule for when to make the call. If not specified, calls immediately.
        - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
          - `type` 'add_contact_to_group', required: Action type identifier
          - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
        - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
          - `type` 'remove_contact_from_group', required: Action type identifier
          - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
        - object: Updates custom contact information for the current contact (for example, email address or birthdate). The rules editor lists the current variable names available for your project. You can also use a new variable name consisting of letters, numbers, and underscores.
          - `type` 'set_contact_var', required: Action type identifier
          - `variable` string, required: Name of the contact variable to set (without the contact.vars prefix).
          - `value` string: Value to assign to the variable.
        - object: Blocks the current contact.
          - `type` 'block_contact', required: Action type identifier
          - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
        - object: Sends a USSD request from your Android phone to your mobile network. On some mobile networks, USSD requests can be used to check your airtime balance, transfer airtime to other phone numbers, and more. Note that this requires a compatible Android phone running the Telerivet Gateway app. Also, Telerivet cannot automatically invoke USSD requests that return menus or prompts.
          - `type` 'send_ussd', required: Action type identifier
          - `mmi_code` string, required: USSD/MMI code to send (e.g. *123#).
          - `route_id` string: ID of the route to send the USSD request from. If not specified, uses the default route.
        - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
          - `type` 'send_email', required: Action type identifier
          - `to_email` string, required: Recipient email address.
          - `subject` string, required: Email subject line.
          - `body_text` string, required: Email body text.
          - `reply_to` string: Reply-to email address.
          - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
        - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
          - `type` 'set_variable', required: Action type identifier
          - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
          - `value` string, required: Value to assign to the variable.
          - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
          - `value2` string: Second operand for the arithmetic operation (required if op is specified).
        - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
          - `type` 'cancel_scheduled_messages', required: Action type identifier
        - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
          - `type` 'webhook', required: Action type identifier
          - `url` string, required: Webhook URL to receive the HTTP POST request.
          - `secret` string: Secret string passed as POST parameter for request verification.
          - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
            - `name` string, required: POST parameter name (max 100 characters).
            - `value` string, required: Parameter value. May contain [[variables]].
        - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
          - `type` 'log', required: Action type identifier
          - `value` string, required: Log message content.
        - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
          - `type` 'run_script', required: Action type identifier
          - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
        - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
          - `type` 'condition', required: Action type identifier
          - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
            - `type` string, required: Condition type. Values: <code>is</code>, <code>is_not</code>, <code>has_word</code>, <code>does_not_have_word</code>, <code>contains</code>, <code>does_not_contain</code>, <code>starts_with</code>, <code>does_not_start_with</code>, <code>ends_with</code>, <code>does_not_end_with</code>, <code>alpha_before</code>, <code>alpha_after</code>, <code>equals</code>, <code>does_not_equal</code>, <code>less_than</code>, <code>greater_than</code>, <code>less_or_equal</code>, <code>greater_or_equal</code>, <code>contact_is_in_group</code>, <code>contact_not_in_group</code>.
            - `variable` string, required: Variable to test, e.g. <code>[[word1]]</code>, <code>[[contact.name]]</code>. Not required for <code>contact_is_in_group</code> and <code>contact_not_in_group</code> conditions.
            - `value` string, required: Value to compare against (or group name for group membership conditions).
          - `actions` Action[], required: Array of actions to execute if the conditions match.
            - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
              - …
          - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
          - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
        - object: Stops processing rules for this message (for this service only).
          - `type` 'stop', required: Action type identifier
        - object: Waits for a response from the current contact, then processes the response using another set of actions or conditions. Useful for back-and-forth conversations or data collection that requires the contact to send multiple messages.
          - `type` 'wait_response', required: Action type identifier
          - `state_id` string, required: ID of the response handler to process the contact's response.
          - `timeout` object: Schedule for response timeout.
        - object: Triggers a set of actions which can be reused multiple times in the same service.
          - `type` 'run_subroutine', required: Action type identifier
          - `name` string, required: Name of the subroutine to run.
        - object: Triggers another service for the current contact.
          - `type` 'trigger_contact_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
          - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
          - `schedule` object: Schedule for when to trigger the service. If not specified, triggers the service immediately.
        - object: Triggers another service for the current project.
          - `type` 'trigger_project_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
        - object: Creates or retrieves a contact with a particular phone number, and sets that as the "current" contact for subsequent rules. This rule is often used to allow your organization's workers to register other people via SMS, and is typically combined with other rules to add the contact to a group and update their contact information.
          - `type` 'set_contact', required: Action type identifier
          - `phone_number` string, required: Phone number for the contact to use.
    - `subroutines` object[]: Array of subroutine definitions. Subroutines are reusable sets of actions that can be called from the main actions or other subroutines.
      - `name` string, required: Unique name for the subroutine (max 32 characters).
      - `context` string: Context type for the subroutine. If not specified, defaults to the service's context.
      - `actions` Action[], required: Array of actions to execute when the subroutine is called. Available actions depend on the subroutine's context.
        - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
          - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'add_contact_to_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Adds a label to the current message. This makes it easy to segment certain types of messages on your Messages page.
            - `type` 'add_label_to_message', required: Action type identifier
            - `label_name` string, required: Name of the label to add to the message.
          - object: Blocks the current contact.
            - `type` 'block_contact', required: Action type identifier
            - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
          - object: Sends a voice call to the current contact using a specified IVR service.
            - `type` 'call_contact', required: Action type identifier
            - `service_id` string, required: ID of the voice/IVR service to use for the call.
            - `route_id` string: ID of the route to use for the call. If not specified, uses the default route.
            - `schedule` object: Schedule for when to make the call. If not specified, calls immediately.
          - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
            - `type` 'cancel_scheduled_messages', required: Action type identifier
          - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
            - `type` 'condition', required: Action type identifier
            - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
              - …
            - `actions` Action[], required: Array of actions to execute if the conditions match.
            - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
            - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
          - object: Copies the current incoming message to another project within the same organization. This is useful for routing messages to different projects based on message content or contact information, while keeping the original message in the current project.
            - `type` 'copy_message_to_project', required: Action type identifier
            - `project_id` string, required: ID of the project to copy the message to. Must be a project within the same organization.
          - object: Ends the current USSD session.
            - `type` 'end_session', required: Action type identifier
          - object: Within a poll service, skips to the end of the survey.
            - `type` 'end_survey', required: Action type identifier
          - object: Forwards the incoming call to another phone number.
            - `type` 'forward_call', required: Action type identifier
            - `phone_number` string, required: Phone number to forward the call to.
          - object: Hangs up the phone call.
            - `type` 'hangup', required: Action type identifier
          - object: Within a poll service, ignores the current message.
            - `type` 'ignore_message', required: Action type identifier
          - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
            - `type` 'log', required: Action type identifier
            - `value` string, required: Log message content.
          - object: Plays an audio file in WAV or MP3 format in the voice call, which may be uploaded, linked, or recorded via the Telerivet web app. Alternatively, can use text-to-speech to speak a message.
            - `type` 'play_audio', required: Action type identifier
            - `mode` 'file' | 'tts', required: Audio source mode.
            - `audio_url` string: URL of the audio file to play (WAV or MP3). Required when mode is "file".
            - `audio_title` string: Title for the audio file displayed in the web app (not played to the caller). Used when mode is "file".
            - `text` string: Text to speak using text-to-speech. Required when mode is "tts". If mode is "file", the text is not used in the actual call but is displayed as the transcript of the file within the web app.
            - `language` string: Language code for text-to-speech (e.g., "en-US"). Used when mode is "tts".
            - `voice` string: Voice for text-to-speech (e.g., "man", "woman"). Used when mode is "tts".
            - `repeat` boolean: If true, repeat the audio once after a short pause.
          - object: Pushes the message to a HubSpot Help Desk inbox, in a conversation associated with the current contact. HubSpot agents can reply directly to send a reply to the contact.
            - `type` 'push_to_hubspot', required: Action type identifier
            - `integration_id` string, required: ID of the HubSpot channel integration config.
            - `content` string: Content of the message pushed to HubSpot.
          - object: Pushes the message to a Zendesk support inbox, in a ticket associated with the current contact. Zendesk agents can reply directly to the Zendesk ticket to send a reply to the contact.
            - `type` 'push_to_zendesk', required: Action type identifier
            - `subdomain` string, required: Zendesk subdomain (e.g., "example" for example.zendesk.com).
            - `subject` string, required: Subject line for the Zendesk ticket.
            - `content` string, required: Content of the Zendesk ticket.
          - object: Records an audio response from the caller, saves the recording URL as a custom variable on the message, then triggers the associated response handler.
            - `type` 'record_audio', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the recording is received (e.g., "recording"). Also used as the name of the variable where the recording URL will be stored (e.g. [[vars.recording]]).
          - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'remove_contact_from_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Within a poll service, repeats the current question again.
            - `type` 'repeat_question', required: Action type identifier
          - object: Sends a text reply to the sender. Optionally, the reply can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'reply', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a text reply to the sender (simple version without labels, schedule, or route configuration).
            - `type` 'reply_simple', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `schedule` object: Schedule to send the message at a later time.
          - object: Within a service triggered when a message status changes, will automatically resend the current message via the same route or a different route.
            - `type` 'resend_message', required: Action type identifier
            - `route_id` string: ID of the route to resend the message from. If not specified, uses the original route.
            - `schedule` object: Schedule for when to resend the message. If not specified, resends immediately.
          - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
            - `type` 'run_script', required: Action type identifier
            - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
          - object: Triggers a set of actions which can be reused multiple times in the same service.
            - `type` 'run_subroutine', required: Action type identifier
            - `name` string, required: Name of the subroutine to run.
          - object: Sends airtime to the current contact if they are on a particular mobile network. Acts like a condition, and allows running other actions if the contact is on one of the supported networks. An 'else' condition can be added below this action to handle contacts that are not on the supported mobile networks.
            - `type` 'send_airtime', required: Action type identifier
            - `provider_id` string, required: ID of the airtime provider to use.
            - `products` object[], required: Array of product configurations for different mobile networks or countries.
              - …
            - `actions` Action[]: Array of actions to execute if the contact is on a supported mobile network.
            - `on_success` string: Name of subroutine to execute when the airtime transaction succeeds.
            - `on_failure` string: Name of subroutine to execute when the airtime transaction fails.
          - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
            - `type` 'send_email', required: Action type identifier
            - `to_email` string, required: Recipient email address.
            - `subject` string, required: Email subject line.
            - `body_text` string, required: Email body text.
            - `reply_to` string: Reply-to email address.
            - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
          - object: Sends a text message to any phone number. Optionally, the message can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'send_text', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `to_number` string, required: Phone number to send the message to.
          - object: Sends a text message to the current contact.
            - `type` 'send_text_to_contact', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a SMS message to a group defined on your Contacts page. Optionally, you can exclude the message sender from receiving the message (common when implementing a group chat system).
            - `type` 'send_text_to_group', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `group_name` string, required: Name of the group to send the message to.
            - `exclude_sender` boolean: If true, exclude the message sender from receiving the group message.
          - object: Sends a USSD request from your Android phone to your mobile network. On some mobile networks, USSD requests can be used to check your airtime balance, transfer airtime to other phone numbers, and more. Note that this requires a compatible Android phone running the Telerivet Gateway app. Also, Telerivet cannot automatically invoke USSD requests that return menus or prompts.
            - `type` 'send_ussd', required: Action type identifier
            - `mmi_code` string, required: USSD/MMI code to send (e.g. *123#).
            - `route_id` string: ID of the route to send the USSD request from. If not specified, uses the default route.
          - object: Shows the specified text in the active USSD session. If this action is followed by a 'Wait for response' action, the text will be displayed as part of a USSD prompt.
            - `type` 'send_ussd_reply', required: Action type identifier
            - `text` string, required: Text to display in the USSD session.
          - object: Creates or retrieves a contact with a particular phone number, and sets that as the "current" contact for subsequent rules. This rule is often used to allow your organization's workers to register other people via SMS, and is typically combined with other rules to add the contact to a group and update their contact information.
            - `type` 'set_contact', required: Action type identifier
            - `phone_number` string, required: Phone number for the contact to use.
          - object: Updates the name of the current contact in Telerivet.
            - `type` 'set_contact_name', required: Action type identifier
            - `name` string, required: Name to assign to the contact.
          - object: Updates custom contact information for the current contact (for example, email address or birthdate). The rules editor lists the current variable names available for your project. You can also use a new variable name consisting of letters, numbers, and underscores.
            - `type` 'set_contact_var', required: Action type identifier
            - `variable` string, required: Name of the contact variable to set (without the contact.vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Updates a custom variable for the current message. When triggered from a service that has a response data table (such as a poll service or custom actions with response handlers), custom message variables set via this action are automatically copied as custom variables on the corresponding response data table row. This is the recommended way to store derived or computed values in the response data table.
            - `type` 'set_message_var', required: Action type identifier
            - `variable` string, required: Name of the message variable to set (without the vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
            - `type` 'set_variable', required: Action type identifier
            - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
            - `value` string, required: Value to assign to the variable.
            - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
            - `value2` string: Second operand for the arithmetic operation (required if op is specified).
          - object: Within a poll service, skips to a question outside the normal order.
            - `type` 'skip_to_question', required: Action type identifier
            - `question_id` string, required: ID of the poll question to skip to.
          - object: Adds a star to the current message. This makes it easy to segment important messages on your Messages page.
            - `type` 'star_message', required: Action type identifier
          - object: Stops processing rules for this message (for this service only).
            - `type` 'stop', required: Action type identifier
          - object: Triggers another service for the current contact.
            - `type` 'trigger_contact_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
            - `schedule` object: Schedule for when to trigger the service. If not specified, triggers the service immediately.
          - object: Triggers another service for the current message.
            - `type` 'trigger_message_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
          - object: Triggers another service for the current project.
            - `type` 'trigger_project_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
          - object: Within a custom route, selects one or more basic routes that can be used to send the message.
            - `type` 'use_phone', required: Action type identifier
            - `phone_ids` string[], required: Array of basic route IDs that can be used to send the message
          - object: Waits for the caller to enter digits on the keypad, saves the input as a custom variable on the message, then triggers the associated response handler.
            - `type` 'wait_for_digits', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the response is received (e.g., "input"). Also used as the name of the variable where the entered digits will be stored (e.g. [[vars.input]].
            - `max_digits` number, required: Maximum number of digits to wait for.
            - `timeout` number: Number of seconds to wait after the last key press. Default: 10.
            - `submit_on_hash` boolean: If true, submit the input when the caller presses #.
          - object: Waits for the caller to press a single key on the keypad, saves the input as a custom variable on the message, then triggers the associated response handler.
            - `type` 'wait_for_key', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the key is pressed (e.g., "input"). Also used as the name of the variable where the pressed key will be stored (e.g. [[vars.input]]).
          - object: Waits for a response from the current contact, then processes the response using another set of actions or conditions. Useful for back-and-forth conversations or data collection that requires the contact to send multiple messages.
            - `type` 'wait_response', required: Action type identifier
            - `state_id` string, required: ID of the response handler to process the contact's response.
            - `timeout` object: Schedule for response timeout.
          - object: Prompts the user for input in the active USSD session, saves the response as a custom variable on the message, and triggers the associated response handler.
            - `type` 'wait_ussd_response', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the response is received (e.g., "input"). Also used as the name of the variable where the USSD response will be stored (e.g. [[vars.input]]).
          - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
            - `type` 'webhook', required: Action type identifier
            - `url` string, required: Webhook URL to receive the HTTP POST request.
            - `secret` string: Secret string passed as POST parameter for request verification.
            - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
              - …
    - `response_handlers` object[]: Array of response handler definitions. Response handlers are triggered when the service is waiting for input (e.g., after `wait_response` actions).
      - `state_id` string, required: Unique state identifier for this response handler. Must be a valid variable name and cannot be "initial".
      - `actions` MessageAction[], required: Array of actions to execute when a response is received in this state.
        - union: An action available for `incoming_message_actions` and `message_actions` service types.
          - object: Sends a text reply to the sender. Optionally, the reply can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'reply', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a text message to any phone number. Optionally, the message can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'send_text', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `to_number` string, required: Phone number to send the message to.
          - object: Sends a SMS message to a group defined on your Contacts page. Optionally, you can exclude the message sender from receiving the message (common when implementing a group chat system).
            - `type` 'send_text_to_group', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `group_name` string, required: Name of the group to send the message to.
            - `exclude_sender` boolean: If true, exclude the message sender from receiving the group message.
          - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'add_contact_to_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'remove_contact_from_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Creates or retrieves a contact with a particular phone number, and sets that as the "current" contact for subsequent rules. This rule is often used to allow your organization's workers to register other people via SMS, and is typically combined with other rules to add the contact to a group and update their contact information.
            - `type` 'set_contact', required: Action type identifier
            - `phone_number` string, required: Phone number for the contact to use.
          - object: Updates the name of the current contact in Telerivet.
            - `type` 'set_contact_name', required: Action type identifier
            - `name` string, required: Name to assign to the contact.
          - object: Updates custom contact information for the current contact (for example, email address or birthdate). The rules editor lists the current variable names available for your project. You can also use a new variable name consisting of letters, numbers, and underscores.
            - `type` 'set_contact_var', required: Action type identifier
            - `variable` string, required: Name of the contact variable to set (without the contact.vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Blocks the current contact.
            - `type` 'block_contact', required: Action type identifier
            - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
          - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
            - `type` 'send_email', required: Action type identifier
            - `to_email` string, required: Recipient email address.
            - `subject` string, required: Email subject line.
            - `body_text` string, required: Email body text.
            - `reply_to` string: Reply-to email address.
            - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
          - object: Sends airtime to the current contact if they are on a particular mobile network. Acts like a condition, and allows running other actions if the contact is on one of the supported networks. An 'else' condition can be added below this action to handle contacts that are not on the supported mobile networks.
            - `type` 'send_airtime', required: Action type identifier
            - `provider_id` string, required: ID of the airtime provider to use.
            - `products` object[], required: Array of product configurations for different mobile networks or countries.
              - …
            - `actions` Action[]: Array of actions to execute if the contact is on a supported mobile network.
              - …
            - `on_success` string: Name of subroutine to execute when the airtime transaction succeeds.
            - `on_failure` string: Name of subroutine to execute when the airtime transaction fails.
          - object: Adds a label to the current message. This makes it easy to segment certain types of messages on your Messages page.
            - `type` 'add_label_to_message', required: Action type identifier
            - `label_name` string, required: Name of the label to add to the message.
          - object: Adds a star to the current message. This makes it easy to segment important messages on your Messages page.
            - `type` 'star_message', required: Action type identifier
          - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
            - `type` 'set_variable', required: Action type identifier
            - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
            - `value` string, required: Value to assign to the variable.
            - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
            - `value2` string: Second operand for the arithmetic operation (required if op is specified).
          - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
            - `type` 'cancel_scheduled_messages', required: Action type identifier
          - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
            - `type` 'webhook', required: Action type identifier
            - `url` string, required: Webhook URL to receive the HTTP POST request.
            - `secret` string: Secret string passed as POST parameter for request verification.
            - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
              - …
          - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
            - `type` 'log', required: Action type identifier
            - `value` string, required: Log message content.
          - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
            - `type` 'run_script', required: Action type identifier
            - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
          - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
            - `type` 'condition', required: Action type identifier
            - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
              - …
            - `actions` Action[], required: Array of actions to execute if the conditions match.
              - …
            - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
            - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
          - object: Triggers another service for the current contact.
            - `type` 'trigger_contact_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
            - `schedule` object: Schedule for when to trigger the service. If not specified, triggers the service immediately.
          - object: Triggers another service for the current message.
            - `type` 'trigger_message_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
          - object: Triggers another service for the current project.
            - `type` 'trigger_project_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
          - object: Stops processing rules for this message (for this service only).
            - `type` 'stop', required: Action type identifier
          - object: Copies the current incoming message to another project within the same organization. This is useful for routing messages to different projects based on message content or contact information, while keeping the original message in the current project.
            - `type` 'copy_message_to_project', required: Action type identifier
            - `project_id` string, required: ID of the project to copy the message to. Must be a project within the same organization.
          - object: Updates a custom variable for the current message. When triggered from a service that has a response data table (such as a poll service or custom actions with response handlers), custom message variables set via this action are automatically copied as custom variables on the corresponding response data table row. This is the recommended way to store derived or computed values in the response data table.
            - `type` 'set_message_var', required: Action type identifier
            - `variable` string, required: Name of the message variable to set (without the vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Waits for a response from the current contact, then processes the response using another set of actions or conditions. Useful for back-and-forth conversations or data collection that requires the contact to send multiple messages.
            - `type` 'wait_response', required: Action type identifier
            - `state_id` string, required: ID of the response handler to process the contact's response.
            - `timeout` object: Schedule for response timeout.
          - object: Sends a USSD request from your Android phone to your mobile network. On some mobile networks, USSD requests can be used to check your airtime balance, transfer airtime to other phone numbers, and more. Note that this requires a compatible Android phone running the Telerivet Gateway app. Also, Telerivet cannot automatically invoke USSD requests that return menus or prompts.
            - `type` 'send_ussd', required: Action type identifier
            - `mmi_code` string, required: USSD/MMI code to send (e.g. *123#).
            - `route_id` string: ID of the route to send the USSD request from. If not specified, uses the default route.
          - object: Triggers a set of actions which can be reused multiple times in the same service.
            - `type` 'run_subroutine', required: Action type identifier
            - `name` string, required: Name of the subroutine to run.
          - object: Sends a voice call to the current contact using a specified IVR service.
            - `type` 'call_contact', required: Action type identifier
            - `service_id` string, required: ID of the voice/IVR service to use for the call.
            - `route_id` string: ID of the route to use for the call. If not specified, uses the default route.
            - `schedule` object: Schedule for when to make the call. If not specified, calls immediately.
          - object: Pushes the message to a Zendesk support inbox, in a ticket associated with the current contact. Zendesk agents can reply directly to the Zendesk ticket to send a reply to the contact.
            - `type` 'push_to_zendesk', required: Action type identifier
            - `subdomain` string, required: Zendesk subdomain (e.g., "example" for example.zendesk.com).
            - `subject` string, required: Subject line for the Zendesk ticket.
            - `content` string, required: Content of the Zendesk ticket.
          - object: Pushes the message to a HubSpot Help Desk inbox, in a conversation associated with the current contact. HubSpot agents can reply directly to send a reply to the contact.
            - `type` 'push_to_hubspot', required: Action type identifier
            - `integration_id` string, required: ID of the HubSpot channel integration config.
            - `content` string: Content of the message pushed to HubSpot.
  - ServiceConfigMessageActions: Configuration for `message_actions` service type.
    - `actions` MessageAction[]: Array of actions to execute. Each action is an object with a `type` property and additional properties depending on the action type. See <a href="/api/rules_engine#actions">Action Reference</a> for documentation of available action types.
      - union: An action available for `incoming_message_actions` and `message_actions` service types.
        - object: Sends a text reply to the sender. Optionally, the reply can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
          - `type` 'reply', required: Action type identifier
          - `body` MessageBodyWithVariants, required
            - `content` string: Text content of the message.
            - `media` object[]: Array of media attachments.
              - …
            - `route_params` object: Route-specific parameters for the message. See <a href="#route_params">Route-Specific Parameters</a>.
            - `track_clicks` boolean: Whether to shorten links and track link clicks in this message.
            - `short_link_params` object: Parameters for short links when track_clicks is enabled.
              - …
            - `variants` object[]: Allows sending different message bodies depending on the route that sends the message, or the contact that the message is sent to. Each variant has conditions and its own message body. When each message is sent, the first variant whose conditions match is used instead of the default message body; if no variant matches, the default message body is used. A variant replaces the entire message body: content, media, route_params, track_clicks and short_link_params that are not specified in the variant are empty, not inherited from the default message body. Conditions are evaluated when the message is sent by a particular basic route, and can use the same variables as outgoing message content: contact variables such as [[contact.name]] and [[contact.vars.\*]], [[to_number]], [[time]], [[project.\*]], and variables of the basic route sending the message: [[phone.type]] (e.g. whatsapp), [[phone.id]], [[phone.vars.\*]], and [[phone.supports_quick_replies]], [[phone.supports_link_button]], [[phone.supports_native_attachments]] (1 if the route supports the feature, otherwise 0). Variables may include filters, e.g. [[contact.vars.language|default:"en"]]. For all available variables, see the <a href='https://telerivet.com/api/rest#variables'>Variable Reference</a>. In services and polls, conditions can't use variables that are only available in the service, such as [[content]] or [[state.\*]] (to use them, first store the value in a contact field, e.g. with a set_contact_var action, and then use [[contact.vars.\*]]). For A/B testing, a variant can have a random split (split_percent) so that it is only used for a random percentage of recipients, e.g. a single variant with split_percent 50 is used for about half of the recipients, and the default message body for the others. A random split can be combined with other conditions to run separate A/B tests for different routes or contacts. Since the first matching variant is used, list more specific variants before more general ones. For example, a variant with a condition `[[contact.vars.language]] is 'fr'` and split_percent 50 must be listed before a variant with only the condition `[[contact.vars.language]] is 'fr'`. Up to 10 variants are supported, each with up to 5 conditions.
              - …
          - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
          - `label_names` string[]: Array of label names to apply to the sent message.
          - `schedule` object: Schedule to send the message at a later time.
          - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
          - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
        - object: Sends a text message to any phone number. Optionally, the message can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
          - `type` 'send_text', required: Action type identifier
          - `body` MessageBodyWithVariants, required
            - `content` string: Text content of the message.
            - `media` object[]: Array of media attachments.
              - …
            - `route_params` object: Route-specific parameters for the message. See <a href="#route_params">Route-Specific Parameters</a>.
            - `track_clicks` boolean: Whether to shorten links and track link clicks in this message.
            - `short_link_params` object: Parameters for short links when track_clicks is enabled.
              - …
            - `variants` object[]: Allows sending different message bodies depending on the route that sends the message, or the contact that the message is sent to. Each variant has conditions and its own message body. When each message is sent, the first variant whose conditions match is used instead of the default message body; if no variant matches, the default message body is used. A variant replaces the entire message body: content, media, route_params, track_clicks and short_link_params that are not specified in the variant are empty, not inherited from the default message body. Conditions are evaluated when the message is sent by a particular basic route, and can use the same variables as outgoing message content: contact variables such as [[contact.name]] and [[contact.vars.\*]], [[to_number]], [[time]], [[project.\*]], and variables of the basic route sending the message: [[phone.type]] (e.g. whatsapp), [[phone.id]], [[phone.vars.\*]], and [[phone.supports_quick_replies]], [[phone.supports_link_button]], [[phone.supports_native_attachments]] (1 if the route supports the feature, otherwise 0). Variables may include filters, e.g. [[contact.vars.language|default:"en"]]. For all available variables, see the <a href='https://telerivet.com/api/rest#variables'>Variable Reference</a>. In services and polls, conditions can't use variables that are only available in the service, such as [[content]] or [[state.\*]] (to use them, first store the value in a contact field, e.g. with a set_contact_var action, and then use [[contact.vars.\*]]). For A/B testing, a variant can have a random split (split_percent) so that it is only used for a random percentage of recipients, e.g. a single variant with split_percent 50 is used for about half of the recipients, and the default message body for the others. A random split can be combined with other conditions to run separate A/B tests for different routes or contacts. Since the first matching variant is used, list more specific variants before more general ones. For example, a variant with a condition `[[contact.vars.language]] is 'fr'` and split_percent 50 must be listed before a variant with only the condition `[[contact.vars.language]] is 'fr'`. Up to 10 variants are supported, each with up to 5 conditions.
              - …
          - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
          - `label_names` string[]: Array of label names to apply to the sent message.
          - `schedule` object: Schedule to send the message at a later time.
          - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
          - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - `to_number` string, required: Phone number to send the message to.
        - object: Sends a SMS message to a group defined on your Contacts page. Optionally, you can exclude the message sender from receiving the message (common when implementing a group chat system).
          - `type` 'send_text_to_group', required: Action type identifier
          - `body` MessageBodyWithVariants, required
            - `content` string: Text content of the message.
            - `media` object[]: Array of media attachments.
              - …
            - `route_params` object: Route-specific parameters for the message. See <a href="#route_params">Route-Specific Parameters</a>.
            - `track_clicks` boolean: Whether to shorten links and track link clicks in this message.
            - `short_link_params` object: Parameters for short links when track_clicks is enabled.
              - …
            - `variants` object[]: Allows sending different message bodies depending on the route that sends the message, or the contact that the message is sent to. Each variant has conditions and its own message body. When each message is sent, the first variant whose conditions match is used instead of the default message body; if no variant matches, the default message body is used. A variant replaces the entire message body: content, media, route_params, track_clicks and short_link_params that are not specified in the variant are empty, not inherited from the default message body. Conditions are evaluated when the message is sent by a particular basic route, and can use the same variables as outgoing message content: contact variables such as [[contact.name]] and [[contact.vars.\*]], [[to_number]], [[time]], [[project.\*]], and variables of the basic route sending the message: [[phone.type]] (e.g. whatsapp), [[phone.id]], [[phone.vars.\*]], and [[phone.supports_quick_replies]], [[phone.supports_link_button]], [[phone.supports_native_attachments]] (1 if the route supports the feature, otherwise 0). Variables may include filters, e.g. [[contact.vars.language|default:"en"]]. For all available variables, see the <a href='https://telerivet.com/api/rest#variables'>Variable Reference</a>. In services and polls, conditions can't use variables that are only available in the service, such as [[content]] or [[state.\*]] (to use them, first store the value in a contact field, e.g. with a set_contact_var action, and then use [[contact.vars.\*]]). For A/B testing, a variant can have a random split (split_percent) so that it is only used for a random percentage of recipients, e.g. a single variant with split_percent 50 is used for about half of the recipients, and the default message body for the others. A random split can be combined with other conditions to run separate A/B tests for different routes or contacts. Since the first matching variant is used, list more specific variants before more general ones. For example, a variant with a condition `[[contact.vars.language]] is 'fr'` and split_percent 50 must be listed before a variant with only the condition `[[contact.vars.language]] is 'fr'`. Up to 10 variants are supported, each with up to 5 conditions.
              - …
          - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
          - `label_names` string[]: Array of label names to apply to the sent message.
          - `schedule` object: Schedule to send the message at a later time.
          - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
          - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - `group_name` string, required: Name of the group to send the message to.
          - `exclude_sender` boolean: If true, exclude the message sender from receiving the group message.
        - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
          - `type` 'add_contact_to_group', required: Action type identifier
          - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
        - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
          - `type` 'remove_contact_from_group', required: Action type identifier
          - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
        - object: Creates or retrieves a contact with a particular phone number, and sets that as the "current" contact for subsequent rules. This rule is often used to allow your organization's workers to register other people via SMS, and is typically combined with other rules to add the contact to a group and update their contact information.
          - `type` 'set_contact', required: Action type identifier
          - `phone_number` string, required: Phone number for the contact to use.
        - object: Updates the name of the current contact in Telerivet.
          - `type` 'set_contact_name', required: Action type identifier
          - `name` string, required: Name to assign to the contact.
        - object: Updates custom contact information for the current contact (for example, email address or birthdate). The rules editor lists the current variable names available for your project. You can also use a new variable name consisting of letters, numbers, and underscores.
          - `type` 'set_contact_var', required: Action type identifier
          - `variable` string, required: Name of the contact variable to set (without the contact.vars prefix).
          - `value` string: Value to assign to the variable.
        - object: Blocks the current contact.
          - `type` 'block_contact', required: Action type identifier
          - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
        - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
          - `type` 'send_email', required: Action type identifier
          - `to_email` string, required: Recipient email address.
          - `subject` string, required: Email subject line.
          - `body_text` string, required: Email body text.
          - `reply_to` string: Reply-to email address.
          - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
        - object: Sends airtime to the current contact if they are on a particular mobile network. Acts like a condition, and allows running other actions if the contact is on one of the supported networks. An 'else' condition can be added below this action to handle contacts that are not on the supported mobile networks.
          - `type` 'send_airtime', required: Action type identifier
          - `provider_id` string, required: ID of the airtime provider to use.
          - `products` object[], required: Array of product configurations for different mobile networks or countries.
            - `country` string, required: Two-letter country code (e.g., KE for Kenya).
            - `operator_id` string: ID of the mobile network operator (according to the airtime provider). Required if the provider supports multiple operators.
            - `product_id` string, required: ID of the airtime product to send (according to the airtime provider).
            - `amount` number: Amount of airtime to send. Required for variable-amount products.
          - `actions` Action[]: Array of actions to execute if the contact is on a supported mobile network.
            - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
              - …
          - `on_success` string: Name of subroutine to execute when the airtime transaction succeeds.
          - `on_failure` string: Name of subroutine to execute when the airtime transaction fails.
        - object: Adds a label to the current message. This makes it easy to segment certain types of messages on your Messages page.
          - `type` 'add_label_to_message', required: Action type identifier
          - `label_name` string, required: Name of the label to add to the message.
        - object: Adds a star to the current message. This makes it easy to segment important messages on your Messages page.
          - `type` 'star_message', required: Action type identifier
        - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
          - `type` 'set_variable', required: Action type identifier
          - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
          - `value` string, required: Value to assign to the variable.
          - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
          - `value2` string: Second operand for the arithmetic operation (required if op is specified).
        - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
          - `type` 'cancel_scheduled_messages', required: Action type identifier
        - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
          - `type` 'webhook', required: Action type identifier
          - `url` string, required: Webhook URL to receive the HTTP POST request.
          - `secret` string: Secret string passed as POST parameter for request verification.
          - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
            - `name` string, required: POST parameter name (max 100 characters).
            - `value` string, required: Parameter value. May contain [[variables]].
        - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
          - `type` 'log', required: Action type identifier
          - `value` string, required: Log message content.
        - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
          - `type` 'run_script', required: Action type identifier
          - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
        - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
          - `type` 'condition', required: Action type identifier
          - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
            - `type` string, required: Condition type. Values: <code>is</code>, <code>is_not</code>, <code>has_word</code>, <code>does_not_have_word</code>, <code>contains</code>, <code>does_not_contain</code>, <code>starts_with</code>, <code>does_not_start_with</code>, <code>ends_with</code>, <code>does_not_end_with</code>, <code>alpha_before</code>, <code>alpha_after</code>, <code>equals</code>, <code>does_not_equal</code>, <code>less_than</code>, <code>greater_than</code>, <code>less_or_equal</code>, <code>greater_or_equal</code>, <code>contact_is_in_group</code>, <code>contact_not_in_group</code>.
            - `variable` string, required: Variable to test, e.g. <code>[[word1]]</code>, <code>[[contact.name]]</code>. Not required for <code>contact_is_in_group</code> and <code>contact_not_in_group</code> conditions.
            - `value` string, required: Value to compare against (or group name for group membership conditions).
          - `actions` Action[], required: Array of actions to execute if the conditions match.
            - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
              - …
          - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
          - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
        - object: Triggers another service for the current contact.
          - `type` 'trigger_contact_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
          - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
          - `schedule` object: Schedule for when to trigger the service. If not specified, triggers the service immediately.
        - object: Triggers another service for the current message.
          - `type` 'trigger_message_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
          - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
        - object: Triggers another service for the current project.
          - `type` 'trigger_project_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
        - object: Stops processing rules for this message (for this service only).
          - `type` 'stop', required: Action type identifier
        - object: Copies the current incoming message to another project within the same organization. This is useful for routing messages to different projects based on message content or contact information, while keeping the original message in the current project.
          - `type` 'copy_message_to_project', required: Action type identifier
          - `project_id` string, required: ID of the project to copy the message to. Must be a project within the same organization.
        - object: Updates a custom variable for the current message. When triggered from a service that has a response data table (such as a poll service or custom actions with response handlers), custom message variables set via this action are automatically copied as custom variables on the corresponding response data table row. This is the recommended way to store derived or computed values in the response data table.
          - `type` 'set_message_var', required: Action type identifier
          - `variable` string, required: Name of the message variable to set (without the vars prefix).
          - `value` string: Value to assign to the variable.
        - object: Waits for a response from the current contact, then processes the response using another set of actions or conditions. Useful for back-and-forth conversations or data collection that requires the contact to send multiple messages.
          - `type` 'wait_response', required: Action type identifier
          - `state_id` string, required: ID of the response handler to process the contact's response.
          - `timeout` object: Schedule for response timeout.
        - object: Sends a USSD request from your Android phone to your mobile network. On some mobile networks, USSD requests can be used to check your airtime balance, transfer airtime to other phone numbers, and more. Note that this requires a compatible Android phone running the Telerivet Gateway app. Also, Telerivet cannot automatically invoke USSD requests that return menus or prompts.
          - `type` 'send_ussd', required: Action type identifier
          - `mmi_code` string, required: USSD/MMI code to send (e.g. *123#).
          - `route_id` string: ID of the route to send the USSD request from. If not specified, uses the default route.
        - object: Triggers a set of actions which can be reused multiple times in the same service.
          - `type` 'run_subroutine', required: Action type identifier
          - `name` string, required: Name of the subroutine to run.
        - object: Sends a voice call to the current contact using a specified IVR service.
          - `type` 'call_contact', required: Action type identifier
          - `service_id` string, required: ID of the voice/IVR service to use for the call.
          - `route_id` string: ID of the route to use for the call. If not specified, uses the default route.
          - `schedule` object: Schedule for when to make the call. If not specified, calls immediately.
        - object: Pushes the message to a Zendesk support inbox, in a ticket associated with the current contact. Zendesk agents can reply directly to the Zendesk ticket to send a reply to the contact.
          - `type` 'push_to_zendesk', required: Action type identifier
          - `subdomain` string, required: Zendesk subdomain (e.g., "example" for example.zendesk.com).
          - `subject` string, required: Subject line for the Zendesk ticket.
          - `content` string, required: Content of the Zendesk ticket.
        - object: Pushes the message to a HubSpot Help Desk inbox, in a conversation associated with the current contact. HubSpot agents can reply directly to send a reply to the contact.
          - `type` 'push_to_hubspot', required: Action type identifier
          - `integration_id` string, required: ID of the HubSpot channel integration config.
          - `content` string: Content of the message pushed to HubSpot.
    - `subroutines` object[]: Array of subroutine definitions. Subroutines are reusable sets of actions that can be called from the main actions or other subroutines.
      - `name` string, required: Unique name for the subroutine (max 32 characters).
      - `context` string: Context type for the subroutine. If not specified, defaults to the service's context.
      - `actions` Action[], required: Array of actions to execute when the subroutine is called. Available actions depend on the subroutine's context.
        - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
          - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'add_contact_to_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Adds a label to the current message. This makes it easy to segment certain types of messages on your Messages page.
            - `type` 'add_label_to_message', required: Action type identifier
            - `label_name` string, required: Name of the label to add to the message.
          - object: Blocks the current contact.
            - `type` 'block_contact', required: Action type identifier
            - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
          - object: Sends a voice call to the current contact using a specified IVR service.
            - `type` 'call_contact', required: Action type identifier
            - `service_id` string, required: ID of the voice/IVR service to use for the call.
            - `route_id` string: ID of the route to use for the call. If not specified, uses the default route.
            - `schedule` object: Schedule for when to make the call. If not specified, calls immediately.
          - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
            - `type` 'cancel_scheduled_messages', required: Action type identifier
          - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
            - `type` 'condition', required: Action type identifier
            - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
              - …
            - `actions` Action[], required: Array of actions to execute if the conditions match.
            - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
            - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
          - object: Copies the current incoming message to another project within the same organization. This is useful for routing messages to different projects based on message content or contact information, while keeping the original message in the current project.
            - `type` 'copy_message_to_project', required: Action type identifier
            - `project_id` string, required: ID of the project to copy the message to. Must be a project within the same organization.
          - object: Ends the current USSD session.
            - `type` 'end_session', required: Action type identifier
          - object: Within a poll service, skips to the end of the survey.
            - `type` 'end_survey', required: Action type identifier
          - object: Forwards the incoming call to another phone number.
            - `type` 'forward_call', required: Action type identifier
            - `phone_number` string, required: Phone number to forward the call to.
          - object: Hangs up the phone call.
            - `type` 'hangup', required: Action type identifier
          - object: Within a poll service, ignores the current message.
            - `type` 'ignore_message', required: Action type identifier
          - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
            - `type` 'log', required: Action type identifier
            - `value` string, required: Log message content.
          - object: Plays an audio file in WAV or MP3 format in the voice call, which may be uploaded, linked, or recorded via the Telerivet web app. Alternatively, can use text-to-speech to speak a message.
            - `type` 'play_audio', required: Action type identifier
            - `mode` 'file' | 'tts', required: Audio source mode.
            - `audio_url` string: URL of the audio file to play (WAV or MP3). Required when mode is "file".
            - `audio_title` string: Title for the audio file displayed in the web app (not played to the caller). Used when mode is "file".
            - `text` string: Text to speak using text-to-speech. Required when mode is "tts". If mode is "file", the text is not used in the actual call but is displayed as the transcript of the file within the web app.
            - `language` string: Language code for text-to-speech (e.g., "en-US"). Used when mode is "tts".
            - `voice` string: Voice for text-to-speech (e.g., "man", "woman"). Used when mode is "tts".
            - `repeat` boolean: If true, repeat the audio once after a short pause.
          - object: Pushes the message to a HubSpot Help Desk inbox, in a conversation associated with the current contact. HubSpot agents can reply directly to send a reply to the contact.
            - `type` 'push_to_hubspot', required: Action type identifier
            - `integration_id` string, required: ID of the HubSpot channel integration config.
            - `content` string: Content of the message pushed to HubSpot.
          - object: Pushes the message to a Zendesk support inbox, in a ticket associated with the current contact. Zendesk agents can reply directly to the Zendesk ticket to send a reply to the contact.
            - `type` 'push_to_zendesk', required: Action type identifier
            - `subdomain` string, required: Zendesk subdomain (e.g., "example" for example.zendesk.com).
            - `subject` string, required: Subject line for the Zendesk ticket.
            - `content` string, required: Content of the Zendesk ticket.
          - object: Records an audio response from the caller, saves the recording URL as a custom variable on the message, then triggers the associated response handler.
            - `type` 'record_audio', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the recording is received (e.g., "recording"). Also used as the name of the variable where the recording URL will be stored (e.g. [[vars.recording]]).
          - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'remove_contact_from_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Within a poll service, repeats the current question again.
            - `type` 'repeat_question', required: Action type identifier
          - object: Sends a text reply to the sender. Optionally, the reply can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'reply', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a text reply to the sender (simple version without labels, schedule, or route configuration).
            - `type` 'reply_simple', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `schedule` object: Schedule to send the message at a later time.
          - object: Within a service triggered when a message status changes, will automatically resend the current message via the same route or a different route.
            - `type` 'resend_message', required: Action type identifier
            - `route_id` string: ID of the route to resend the message from. If not specified, uses the original route.
            - `schedule` object: Schedule for when to resend the message. If not specified, resends immediately.
          - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
            - `type` 'run_script', required: Action type identifier
            - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
          - object: Triggers a set of actions which can be reused multiple times in the same service.
            - `type` 'run_subroutine', required: Action type identifier
            - `name` string, required: Name of the subroutine to run.
          - object: Sends airtime to the current contact if they are on a particular mobile network. Acts like a condition, and allows running other actions if the contact is on one of the supported networks. An 'else' condition can be added below this action to handle contacts that are not on the supported mobile networks.
            - `type` 'send_airtime', required: Action type identifier
            - `provider_id` string, required: ID of the airtime provider to use.
            - `products` object[], required: Array of product configurations for different mobile networks or countries.
              - …
            - `actions` Action[]: Array of actions to execute if the contact is on a supported mobile network.
            - `on_success` string: Name of subroutine to execute when the airtime transaction succeeds.
            - `on_failure` string: Name of subroutine to execute when the airtime transaction fails.
          - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
            - `type` 'send_email', required: Action type identifier
            - `to_email` string, required: Recipient email address.
            - `subject` string, required: Email subject line.
            - `body_text` string, required: Email body text.
            - `reply_to` string: Reply-to email address.
            - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
          - object: Sends a text message to any phone number. Optionally, the message can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'send_text', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `to_number` string, required: Phone number to send the message to.
          - object: Sends a text message to the current contact.
            - `type` 'send_text_to_contact', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a SMS message to a group defined on your Contacts page. Optionally, you can exclude the message sender from receiving the message (common when implementing a group chat system).
            - `type` 'send_text_to_group', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `group_name` string, required: Name of the group to send the message to.
            - `exclude_sender` boolean: If true, exclude the message sender from receiving the group message.
          - object: Sends a USSD request from your Android phone to your mobile network. On some mobile networks, USSD requests can be used to check your airtime balance, transfer airtime to other phone numbers, and more. Note that this requires a compatible Android phone running the Telerivet Gateway app. Also, Telerivet cannot automatically invoke USSD requests that return menus or prompts.
            - `type` 'send_ussd', required: Action type identifier
            - `mmi_code` string, required: USSD/MMI code to send (e.g. *123#).
            - `route_id` string: ID of the route to send the USSD request from. If not specified, uses the default route.
          - object: Shows the specified text in the active USSD session. If this action is followed by a 'Wait for response' action, the text will be displayed as part of a USSD prompt.
            - `type` 'send_ussd_reply', required: Action type identifier
            - `text` string, required: Text to display in the USSD session.
          - object: Creates or retrieves a contact with a particular phone number, and sets that as the "current" contact for subsequent rules. This rule is often used to allow your organization's workers to register other people via SMS, and is typically combined with other rules to add the contact to a group and update their contact information.
            - `type` 'set_contact', required: Action type identifier
            - `phone_number` string, required: Phone number for the contact to use.
          - object: Updates the name of the current contact in Telerivet.
            - `type` 'set_contact_name', required: Action type identifier
            - `name` string, required: Name to assign to the contact.
          - object: Updates custom contact information for the current contact (for example, email address or birthdate). The rules editor lists the current variable names available for your project. You can also use a new variable name consisting of letters, numbers, and underscores.
            - `type` 'set_contact_var', required: Action type identifier
            - `variable` string, required: Name of the contact variable to set (without the contact.vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Updates a custom variable for the current message. When triggered from a service that has a response data table (such as a poll service or custom actions with response handlers), custom message variables set via this action are automatically copied as custom variables on the corresponding response data table row. This is the recommended way to store derived or computed values in the response data table.
            - `type` 'set_message_var', required: Action type identifier
            - `variable` string, required: Name of the message variable to set (without the vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
            - `type` 'set_variable', required: Action type identifier
            - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
            - `value` string, required: Value to assign to the variable.
            - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
            - `value2` string: Second operand for the arithmetic operation (required if op is specified).
          - object: Within a poll service, skips to a question outside the normal order.
            - `type` 'skip_to_question', required: Action type identifier
            - `question_id` string, required: ID of the poll question to skip to.
          - object: Adds a star to the current message. This makes it easy to segment important messages on your Messages page.
            - `type` 'star_message', required: Action type identifier
          - object: Stops processing rules for this message (for this service only).
            - `type` 'stop', required: Action type identifier
          - object: Triggers another service for the current contact.
            - `type` 'trigger_contact_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
            - `schedule` object: Schedule for when to trigger the service. If not specified, triggers the service immediately.
          - object: Triggers another service for the current message.
            - `type` 'trigger_message_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
          - object: Triggers another service for the current project.
            - `type` 'trigger_project_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
          - object: Within a custom route, selects one or more basic routes that can be used to send the message.
            - `type` 'use_phone', required: Action type identifier
            - `phone_ids` string[], required: Array of basic route IDs that can be used to send the message
          - object: Waits for the caller to enter digits on the keypad, saves the input as a custom variable on the message, then triggers the associated response handler.
            - `type` 'wait_for_digits', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the response is received (e.g., "input"). Also used as the name of the variable where the entered digits will be stored (e.g. [[vars.input]].
            - `max_digits` number, required: Maximum number of digits to wait for.
            - `timeout` number: Number of seconds to wait after the last key press. Default: 10.
            - `submit_on_hash` boolean: If true, submit the input when the caller presses #.
          - object: Waits for the caller to press a single key on the keypad, saves the input as a custom variable on the message, then triggers the associated response handler.
            - `type` 'wait_for_key', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the key is pressed (e.g., "input"). Also used as the name of the variable where the pressed key will be stored (e.g. [[vars.input]]).
          - object: Waits for a response from the current contact, then processes the response using another set of actions or conditions. Useful for back-and-forth conversations or data collection that requires the contact to send multiple messages.
            - `type` 'wait_response', required: Action type identifier
            - `state_id` string, required: ID of the response handler to process the contact's response.
            - `timeout` object: Schedule for response timeout.
          - object: Prompts the user for input in the active USSD session, saves the response as a custom variable on the message, and triggers the associated response handler.
            - `type` 'wait_ussd_response', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the response is received (e.g., "input"). Also used as the name of the variable where the USSD response will be stored (e.g. [[vars.input]]).
          - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
            - `type` 'webhook', required: Action type identifier
            - `url` string, required: Webhook URL to receive the HTTP POST request.
            - `secret` string: Secret string passed as POST parameter for request verification.
            - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
              - …
    - `response_handlers` object[]: Array of response handler definitions. Response handlers are triggered when the service is waiting for input (e.g., after `wait_response` actions).
      - `state_id` string, required: Unique state identifier for this response handler. Must be a valid variable name and cannot be "initial".
      - `actions` MessageAction[], required: Array of actions to execute when a response is received in this state.
        - union: An action available for `incoming_message_actions` and `message_actions` service types.
          - object: Sends a text reply to the sender. Optionally, the reply can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'reply', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a text message to any phone number. Optionally, the message can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'send_text', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `to_number` string, required: Phone number to send the message to.
          - object: Sends a SMS message to a group defined on your Contacts page. Optionally, you can exclude the message sender from receiving the message (common when implementing a group chat system).
            - `type` 'send_text_to_group', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `group_name` string, required: Name of the group to send the message to.
            - `exclude_sender` boolean: If true, exclude the message sender from receiving the group message.
          - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'add_contact_to_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'remove_contact_from_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Creates or retrieves a contact with a particular phone number, and sets that as the "current" contact for subsequent rules. This rule is often used to allow your organization's workers to register other people via SMS, and is typically combined with other rules to add the contact to a group and update their contact information.
            - `type` 'set_contact', required: Action type identifier
            - `phone_number` string, required: Phone number for the contact to use.
          - object: Updates the name of the current contact in Telerivet.
            - `type` 'set_contact_name', required: Action type identifier
            - `name` string, required: Name to assign to the contact.
          - object: Updates custom contact information for the current contact (for example, email address or birthdate). The rules editor lists the current variable names available for your project. You can also use a new variable name consisting of letters, numbers, and underscores.
            - `type` 'set_contact_var', required: Action type identifier
            - `variable` string, required: Name of the contact variable to set (without the contact.vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Blocks the current contact.
            - `type` 'block_contact', required: Action type identifier
            - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
          - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
            - `type` 'send_email', required: Action type identifier
            - `to_email` string, required: Recipient email address.
            - `subject` string, required: Email subject line.
            - `body_text` string, required: Email body text.
            - `reply_to` string: Reply-to email address.
            - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
          - object: Sends airtime to the current contact if they are on a particular mobile network. Acts like a condition, and allows running other actions if the contact is on one of the supported networks. An 'else' condition can be added below this action to handle contacts that are not on the supported mobile networks.
            - `type` 'send_airtime', required: Action type identifier
            - `provider_id` string, required: ID of the airtime provider to use.
            - `products` object[], required: Array of product configurations for different mobile networks or countries.
              - …
            - `actions` Action[]: Array of actions to execute if the contact is on a supported mobile network.
              - …
            - `on_success` string: Name of subroutine to execute when the airtime transaction succeeds.
            - `on_failure` string: Name of subroutine to execute when the airtime transaction fails.
          - object: Adds a label to the current message. This makes it easy to segment certain types of messages on your Messages page.
            - `type` 'add_label_to_message', required: Action type identifier
            - `label_name` string, required: Name of the label to add to the message.
          - object: Adds a star to the current message. This makes it easy to segment important messages on your Messages page.
            - `type` 'star_message', required: Action type identifier
          - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
            - `type` 'set_variable', required: Action type identifier
            - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
            - `value` string, required: Value to assign to the variable.
            - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
            - `value2` string: Second operand for the arithmetic operation (required if op is specified).
          - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
            - `type` 'cancel_scheduled_messages', required: Action type identifier
          - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
            - `type` 'webhook', required: Action type identifier
            - `url` string, required: Webhook URL to receive the HTTP POST request.
            - `secret` string: Secret string passed as POST parameter for request verification.
            - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
              - …
          - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
            - `type` 'log', required: Action type identifier
            - `value` string, required: Log message content.
          - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
            - `type` 'run_script', required: Action type identifier
            - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
          - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
            - `type` 'condition', required: Action type identifier
            - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
              - …
            - `actions` Action[], required: Array of actions to execute if the conditions match.
              - …
            - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
            - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
          - object: Triggers another service for the current contact.
            - `type` 'trigger_contact_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
            - `schedule` object: Schedule for when to trigger the service. If not specified, triggers the service immediately.
          - object: Triggers another service for the current message.
            - `type` 'trigger_message_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
          - object: Triggers another service for the current project.
            - `type` 'trigger_project_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
          - object: Stops processing rules for this message (for this service only).
            - `type` 'stop', required: Action type identifier
          - object: Copies the current incoming message to another project within the same organization. This is useful for routing messages to different projects based on message content or contact information, while keeping the original message in the current project.
            - `type` 'copy_message_to_project', required: Action type identifier
            - `project_id` string, required: ID of the project to copy the message to. Must be a project within the same organization.
          - object: Updates a custom variable for the current message. When triggered from a service that has a response data table (such as a poll service or custom actions with response handlers), custom message variables set via this action are automatically copied as custom variables on the corresponding response data table row. This is the recommended way to store derived or computed values in the response data table.
            - `type` 'set_message_var', required: Action type identifier
            - `variable` string, required: Name of the message variable to set (without the vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Waits for a response from the current contact, then processes the response using another set of actions or conditions. Useful for back-and-forth conversations or data collection that requires the contact to send multiple messages.
            - `type` 'wait_response', required: Action type identifier
            - `state_id` string, required: ID of the response handler to process the contact's response.
            - `timeout` object: Schedule for response timeout.
          - object: Sends a USSD request from your Android phone to your mobile network. On some mobile networks, USSD requests can be used to check your airtime balance, transfer airtime to other phone numbers, and more. Note that this requires a compatible Android phone running the Telerivet Gateway app. Also, Telerivet cannot automatically invoke USSD requests that return menus or prompts.
            - `type` 'send_ussd', required: Action type identifier
            - `mmi_code` string, required: USSD/MMI code to send (e.g. *123#).
            - `route_id` string: ID of the route to send the USSD request from. If not specified, uses the default route.
          - object: Triggers a set of actions which can be reused multiple times in the same service.
            - `type` 'run_subroutine', required: Action type identifier
            - `name` string, required: Name of the subroutine to run.
          - object: Sends a voice call to the current contact using a specified IVR service.
            - `type` 'call_contact', required: Action type identifier
            - `service_id` string, required: ID of the voice/IVR service to use for the call.
            - `route_id` string: ID of the route to use for the call. If not specified, uses the default route.
            - `schedule` object: Schedule for when to make the call. If not specified, calls immediately.
          - object: Pushes the message to a Zendesk support inbox, in a ticket associated with the current contact. Zendesk agents can reply directly to the Zendesk ticket to send a reply to the contact.
            - `type` 'push_to_zendesk', required: Action type identifier
            - `subdomain` string, required: Zendesk subdomain (e.g., "example" for example.zendesk.com).
            - `subject` string, required: Subject line for the Zendesk ticket.
            - `content` string, required: Content of the Zendesk ticket.
          - object: Pushes the message to a HubSpot Help Desk inbox, in a conversation associated with the current contact. HubSpot agents can reply directly to send a reply to the contact.
            - `type` 'push_to_hubspot', required: Action type identifier
            - `integration_id` string, required: ID of the HubSpot channel integration config.
            - `content` string: Content of the message pushed to HubSpot.
  - ServiceConfigProjectActions: Configuration for `project_actions` service type.
    - `actions` ProjectAction[]: Array of actions to execute. Each action is an object with a `type` property and additional properties depending on the action type. See <a href="/api/rules_engine#actions">Action Reference</a> for documentation of available action types.
      - union: An action available for `project_actions` and `scheduled_actions` service types.
        - object: Sends a text message to any phone number. Optionally, the message can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
          - `type` 'send_text', required: Action type identifier
          - `body` MessageBodyWithVariants, required
            - `content` string: Text content of the message.
            - `media` object[]: Array of media attachments.
              - …
            - `route_params` object: Route-specific parameters for the message. See <a href="#route_params">Route-Specific Parameters</a>.
            - `track_clicks` boolean: Whether to shorten links and track link clicks in this message.
            - `short_link_params` object: Parameters for short links when track_clicks is enabled.
              - …
            - `variants` object[]: Allows sending different message bodies depending on the route that sends the message, or the contact that the message is sent to. Each variant has conditions and its own message body. When each message is sent, the first variant whose conditions match is used instead of the default message body; if no variant matches, the default message body is used. A variant replaces the entire message body: content, media, route_params, track_clicks and short_link_params that are not specified in the variant are empty, not inherited from the default message body. Conditions are evaluated when the message is sent by a particular basic route, and can use the same variables as outgoing message content: contact variables such as [[contact.name]] and [[contact.vars.\*]], [[to_number]], [[time]], [[project.\*]], and variables of the basic route sending the message: [[phone.type]] (e.g. whatsapp), [[phone.id]], [[phone.vars.\*]], and [[phone.supports_quick_replies]], [[phone.supports_link_button]], [[phone.supports_native_attachments]] (1 if the route supports the feature, otherwise 0). Variables may include filters, e.g. [[contact.vars.language|default:"en"]]. For all available variables, see the <a href='https://telerivet.com/api/rest#variables'>Variable Reference</a>. In services and polls, conditions can't use variables that are only available in the service, such as [[content]] or [[state.\*]] (to use them, first store the value in a contact field, e.g. with a set_contact_var action, and then use [[contact.vars.\*]]). For A/B testing, a variant can have a random split (split_percent) so that it is only used for a random percentage of recipients, e.g. a single variant with split_percent 50 is used for about half of the recipients, and the default message body for the others. A random split can be combined with other conditions to run separate A/B tests for different routes or contacts. Since the first matching variant is used, list more specific variants before more general ones. For example, a variant with a condition `[[contact.vars.language]] is 'fr'` and split_percent 50 must be listed before a variant with only the condition `[[contact.vars.language]] is 'fr'`. Up to 10 variants are supported, each with up to 5 conditions.
              - …
          - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
          - `label_names` string[]: Array of label names to apply to the sent message.
          - `schedule` object: Schedule to send the message at a later time.
          - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
          - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - `to_number` string, required: Phone number to send the message to.
        - object: Sends a SMS message to a group defined on your Contacts page. Optionally, you can exclude the message sender from receiving the message (common when implementing a group chat system).
          - `type` 'send_text_to_group', required: Action type identifier
          - `body` MessageBodyWithVariants, required
            - `content` string: Text content of the message.
            - `media` object[]: Array of media attachments.
              - …
            - `route_params` object: Route-specific parameters for the message. See <a href="#route_params">Route-Specific Parameters</a>.
            - `track_clicks` boolean: Whether to shorten links and track link clicks in this message.
            - `short_link_params` object: Parameters for short links when track_clicks is enabled.
              - …
            - `variants` object[]: Allows sending different message bodies depending on the route that sends the message, or the contact that the message is sent to. Each variant has conditions and its own message body. When each message is sent, the first variant whose conditions match is used instead of the default message body; if no variant matches, the default message body is used. A variant replaces the entire message body: content, media, route_params, track_clicks and short_link_params that are not specified in the variant are empty, not inherited from the default message body. Conditions are evaluated when the message is sent by a particular basic route, and can use the same variables as outgoing message content: contact variables such as [[contact.name]] and [[contact.vars.\*]], [[to_number]], [[time]], [[project.\*]], and variables of the basic route sending the message: [[phone.type]] (e.g. whatsapp), [[phone.id]], [[phone.vars.\*]], and [[phone.supports_quick_replies]], [[phone.supports_link_button]], [[phone.supports_native_attachments]] (1 if the route supports the feature, otherwise 0). Variables may include filters, e.g. [[contact.vars.language|default:"en"]]. For all available variables, see the <a href='https://telerivet.com/api/rest#variables'>Variable Reference</a>. In services and polls, conditions can't use variables that are only available in the service, such as [[content]] or [[state.\*]] (to use them, first store the value in a contact field, e.g. with a set_contact_var action, and then use [[contact.vars.\*]]). For A/B testing, a variant can have a random split (split_percent) so that it is only used for a random percentage of recipients, e.g. a single variant with split_percent 50 is used for about half of the recipients, and the default message body for the others. A random split can be combined with other conditions to run separate A/B tests for different routes or contacts. Since the first matching variant is used, list more specific variants before more general ones. For example, a variant with a condition `[[contact.vars.language]] is 'fr'` and split_percent 50 must be listed before a variant with only the condition `[[contact.vars.language]] is 'fr'`. Up to 10 variants are supported, each with up to 5 conditions.
              - …
          - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
          - `label_names` string[]: Array of label names to apply to the sent message.
          - `schedule` object: Schedule to send the message at a later time.
          - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
          - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - `group_name` string, required: Name of the group to send the message to.
          - `exclude_sender` boolean: If true, exclude the message sender from receiving the group message.
        - object: Sends a USSD request from your Android phone to your mobile network. On some mobile networks, USSD requests can be used to check your airtime balance, transfer airtime to other phone numbers, and more. Note that this requires a compatible Android phone running the Telerivet Gateway app. Also, Telerivet cannot automatically invoke USSD requests that return menus or prompts.
          - `type` 'send_ussd', required: Action type identifier
          - `mmi_code` string, required: USSD/MMI code to send (e.g. *123#).
          - `route_id` string: ID of the route to send the USSD request from. If not specified, uses the default route.
        - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
          - `type` 'send_email', required: Action type identifier
          - `to_email` string, required: Recipient email address.
          - `subject` string, required: Email subject line.
          - `body_text` string, required: Email body text.
          - `reply_to` string: Reply-to email address.
          - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
        - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
          - `type` 'set_variable', required: Action type identifier
          - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
          - `value` string, required: Value to assign to the variable.
          - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
          - `value2` string: Second operand for the arithmetic operation (required if op is specified).
        - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
          - `type` 'webhook', required: Action type identifier
          - `url` string, required: Webhook URL to receive the HTTP POST request.
          - `secret` string: Secret string passed as POST parameter for request verification.
          - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
            - `name` string, required: POST parameter name (max 100 characters).
            - `value` string, required: Parameter value. May contain [[variables]].
        - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
          - `type` 'log', required: Action type identifier
          - `value` string, required: Log message content.
        - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
          - `type` 'run_script', required: Action type identifier
          - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
        - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
          - `type` 'condition', required: Action type identifier
          - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
            - `type` string, required: Condition type. Values: <code>is</code>, <code>is_not</code>, <code>has_word</code>, <code>does_not_have_word</code>, <code>contains</code>, <code>does_not_contain</code>, <code>starts_with</code>, <code>does_not_start_with</code>, <code>ends_with</code>, <code>does_not_end_with</code>, <code>alpha_before</code>, <code>alpha_after</code>, <code>equals</code>, <code>does_not_equal</code>, <code>less_than</code>, <code>greater_than</code>, <code>less_or_equal</code>, <code>greater_or_equal</code>, <code>contact_is_in_group</code>, <code>contact_not_in_group</code>.
            - `variable` string, required: Variable to test, e.g. <code>[[word1]]</code>, <code>[[contact.name]]</code>. Not required for <code>contact_is_in_group</code> and <code>contact_not_in_group</code> conditions.
            - `value` string, required: Value to compare against (or group name for group membership conditions).
          - `actions` Action[], required: Array of actions to execute if the conditions match.
            - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
              - …
          - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
          - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
        - object: Stops processing rules for this message (for this service only).
          - `type` 'stop', required: Action type identifier
        - object: Triggers a set of actions which can be reused multiple times in the same service.
          - `type` 'run_subroutine', required: Action type identifier
          - `name` string, required: Name of the subroutine to run.
        - object: Triggers another service for the current project.
          - `type` 'trigger_project_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
    - `subroutines` object[]: Array of subroutine definitions. Subroutines are reusable sets of actions that can be called from the main actions or other subroutines.
      - `name` string, required: Unique name for the subroutine (max 32 characters).
      - `context` string: Context type for the subroutine. If not specified, defaults to the service's context.
      - `actions` Action[], required: Array of actions to execute when the subroutine is called. Available actions depend on the subroutine's context.
        - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
          - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'add_contact_to_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Adds a label to the current message. This makes it easy to segment certain types of messages on your Messages page.
            - `type` 'add_label_to_message', required: Action type identifier
            - `label_name` string, required: Name of the label to add to the message.
          - object: Blocks the current contact.
            - `type` 'block_contact', required: Action type identifier
            - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
          - object: Sends a voice call to the current contact using a specified IVR service.
            - `type` 'call_contact', required: Action type identifier
            - `service_id` string, required: ID of the voice/IVR service to use for the call.
            - `route_id` string: ID of the route to use for the call. If not specified, uses the default route.
            - `schedule` object: Schedule for when to make the call. If not specified, calls immediately.
          - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
            - `type` 'cancel_scheduled_messages', required: Action type identifier
          - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
            - `type` 'condition', required: Action type identifier
            - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
              - …
            - `actions` Action[], required: Array of actions to execute if the conditions match.
            - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
            - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
          - object: Copies the current incoming message to another project within the same organization. This is useful for routing messages to different projects based on message content or contact information, while keeping the original message in the current project.
            - `type` 'copy_message_to_project', required: Action type identifier
            - `project_id` string, required: ID of the project to copy the message to. Must be a project within the same organization.
          - object: Ends the current USSD session.
            - `type` 'end_session', required: Action type identifier
          - object: Within a poll service, skips to the end of the survey.
            - `type` 'end_survey', required: Action type identifier
          - object: Forwards the incoming call to another phone number.
            - `type` 'forward_call', required: Action type identifier
            - `phone_number` string, required: Phone number to forward the call to.
          - object: Hangs up the phone call.
            - `type` 'hangup', required: Action type identifier
          - object: Within a poll service, ignores the current message.
            - `type` 'ignore_message', required: Action type identifier
          - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
            - `type` 'log', required: Action type identifier
            - `value` string, required: Log message content.
          - object: Plays an audio file in WAV or MP3 format in the voice call, which may be uploaded, linked, or recorded via the Telerivet web app. Alternatively, can use text-to-speech to speak a message.
            - `type` 'play_audio', required: Action type identifier
            - `mode` 'file' | 'tts', required: Audio source mode.
            - `audio_url` string: URL of the audio file to play (WAV or MP3). Required when mode is "file".
            - `audio_title` string: Title for the audio file displayed in the web app (not played to the caller). Used when mode is "file".
            - `text` string: Text to speak using text-to-speech. Required when mode is "tts". If mode is "file", the text is not used in the actual call but is displayed as the transcript of the file within the web app.
            - `language` string: Language code for text-to-speech (e.g., "en-US"). Used when mode is "tts".
            - `voice` string: Voice for text-to-speech (e.g., "man", "woman"). Used when mode is "tts".
            - `repeat` boolean: If true, repeat the audio once after a short pause.
          - object: Pushes the message to a HubSpot Help Desk inbox, in a conversation associated with the current contact. HubSpot agents can reply directly to send a reply to the contact.
            - `type` 'push_to_hubspot', required: Action type identifier
            - `integration_id` string, required: ID of the HubSpot channel integration config.
            - `content` string: Content of the message pushed to HubSpot.
          - object: Pushes the message to a Zendesk support inbox, in a ticket associated with the current contact. Zendesk agents can reply directly to the Zendesk ticket to send a reply to the contact.
            - `type` 'push_to_zendesk', required: Action type identifier
            - `subdomain` string, required: Zendesk subdomain (e.g., "example" for example.zendesk.com).
            - `subject` string, required: Subject line for the Zendesk ticket.
            - `content` string, required: Content of the Zendesk ticket.
          - object: Records an audio response from the caller, saves the recording URL as a custom variable on the message, then triggers the associated response handler.
            - `type` 'record_audio', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the recording is received (e.g., "recording"). Also used as the name of the variable where the recording URL will be stored (e.g. [[vars.recording]]).
          - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'remove_contact_from_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Within a poll service, repeats the current question again.
            - `type` 'repeat_question', required: Action type identifier
          - object: Sends a text reply to the sender. Optionally, the reply can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'reply', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a text reply to the sender (simple version without labels, schedule, or route configuration).
            - `type` 'reply_simple', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `schedule` object: Schedule to send the message at a later time.
          - object: Within a service triggered when a message status changes, will automatically resend the current message via the same route or a different route.
            - `type` 'resend_message', required: Action type identifier
            - `route_id` string: ID of the route to resend the message from. If not specified, uses the original route.
            - `schedule` object: Schedule for when to resend the message. If not specified, resends immediately.
          - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
            - `type` 'run_script', required: Action type identifier
            - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
          - object: Triggers a set of actions which can be reused multiple times in the same service.
            - `type` 'run_subroutine', required: Action type identifier
            - `name` string, required: Name of the subroutine to run.
          - object: Sends airtime to the current contact if they are on a particular mobile network. Acts like a condition, and allows running other actions if the contact is on one of the supported networks. An 'else' condition can be added below this action to handle contacts that are not on the supported mobile networks.
            - `type` 'send_airtime', required: Action type identifier
            - `provider_id` string, required: ID of the airtime provider to use.
            - `products` object[], required: Array of product configurations for different mobile networks or countries.
              - …
            - `actions` Action[]: Array of actions to execute if the contact is on a supported mobile network.
            - `on_success` string: Name of subroutine to execute when the airtime transaction succeeds.
            - `on_failure` string: Name of subroutine to execute when the airtime transaction fails.
          - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
            - `type` 'send_email', required: Action type identifier
            - `to_email` string, required: Recipient email address.
            - `subject` string, required: Email subject line.
            - `body_text` string, required: Email body text.
            - `reply_to` string: Reply-to email address.
            - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
          - object: Sends a text message to any phone number. Optionally, the message can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'send_text', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `to_number` string, required: Phone number to send the message to.
          - object: Sends a text message to the current contact.
            - `type` 'send_text_to_contact', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a SMS message to a group defined on your Contacts page. Optionally, you can exclude the message sender from receiving the message (common when implementing a group chat system).
            - `type` 'send_text_to_group', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
            - `group_name` string, required: Name of the group to send the message to.
            - `exclude_sender` boolean: If true, exclude the message sender from receiving the group message.
          - object: Sends a USSD request from your Android phone to your mobile network. On some mobile networks, USSD requests can be used to check your airtime balance, transfer airtime to other phone numbers, and more. Note that this requires a compatible Android phone running the Telerivet Gateway app. Also, Telerivet cannot automatically invoke USSD requests that return menus or prompts.
            - `type` 'send_ussd', required: Action type identifier
            - `mmi_code` string, required: USSD/MMI code to send (e.g. *123#).
            - `route_id` string: ID of the route to send the USSD request from. If not specified, uses the default route.
          - object: Shows the specified text in the active USSD session. If this action is followed by a 'Wait for response' action, the text will be displayed as part of a USSD prompt.
            - `type` 'send_ussd_reply', required: Action type identifier
            - `text` string, required: Text to display in the USSD session.
          - object: Creates or retrieves a contact with a particular phone number, and sets that as the "current" contact for subsequent rules. This rule is often used to allow your organization's workers to register other people via SMS, and is typically combined with other rules to add the contact to a group and update their contact information.
            - `type` 'set_contact', required: Action type identifier
            - `phone_number` string, required: Phone number for the contact to use.
          - object: Updates the name of the current contact in Telerivet.
            - `type` 'set_contact_name', required: Action type identifier
            - `name` string, required: Name to assign to the contact.
          - object: Updates custom contact information for the current contact (for example, email address or birthdate). The rules editor lists the current variable names available for your project. You can also use a new variable name consisting of letters, numbers, and underscores.
            - `type` 'set_contact_var', required: Action type identifier
            - `variable` string, required: Name of the contact variable to set (without the contact.vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Updates a custom variable for the current message. When triggered from a service that has a response data table (such as a poll service or custom actions with response handlers), custom message variables set via this action are automatically copied as custom variables on the corresponding response data table row. This is the recommended way to store derived or computed values in the response data table.
            - `type` 'set_message_var', required: Action type identifier
            - `variable` string, required: Name of the message variable to set (without the vars prefix).
            - `value` string: Value to assign to the variable.
          - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
            - `type` 'set_variable', required: Action type identifier
            - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
            - `value` string, required: Value to assign to the variable.
            - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
            - `value2` string: Second operand for the arithmetic operation (required if op is specified).
          - object: Within a poll service, skips to a question outside the normal order.
            - `type` 'skip_to_question', required: Action type identifier
            - `question_id` string, required: ID of the poll question to skip to.
          - object: Adds a star to the current message. This makes it easy to segment important messages on your Messages page.
            - `type` 'star_message', required: Action type identifier
          - object: Stops processing rules for this message (for this service only).
            - `type` 'stop', required: Action type identifier
          - object: Triggers another service for the current contact.
            - `type` 'trigger_contact_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
            - `schedule` object: Schedule for when to trigger the service. If not specified, triggers the service immediately.
          - object: Triggers another service for the current message.
            - `type` 'trigger_message_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
            - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
          - object: Triggers another service for the current project.
            - `type` 'trigger_project_service', required: Action type identifier
            - `service_id` string, required: ID of the service to trigger.
          - object: Within a custom route, selects one or more basic routes that can be used to send the message.
            - `type` 'use_phone', required: Action type identifier
            - `phone_ids` string[], required: Array of basic route IDs that can be used to send the message
          - object: Waits for the caller to enter digits on the keypad, saves the input as a custom variable on the message, then triggers the associated response handler.
            - `type` 'wait_for_digits', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the response is received (e.g., "input"). Also used as the name of the variable where the entered digits will be stored (e.g. [[vars.input]].
            - `max_digits` number, required: Maximum number of digits to wait for.
            - `timeout` number: Number of seconds to wait after the last key press. Default: 10.
            - `submit_on_hash` boolean: If true, submit the input when the caller presses #.
          - object: Waits for the caller to press a single key on the keypad, saves the input as a custom variable on the message, then triggers the associated response handler.
            - `type` 'wait_for_key', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the key is pressed (e.g., "input"). Also used as the name of the variable where the pressed key will be stored (e.g. [[vars.input]]).
          - object: Waits for a response from the current contact, then processes the response using another set of actions or conditions. Useful for back-and-forth conversations or data collection that requires the contact to send multiple messages.
            - `type` 'wait_response', required: Action type identifier
            - `state_id` string, required: ID of the response handler to process the contact's response.
            - `timeout` object: Schedule for response timeout.
          - object: Prompts the user for input in the active USSD session, saves the response as a custom variable on the message, and triggers the associated response handler.
            - `type` 'wait_ussd_response', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the response is received (e.g., "input"). Also used as the name of the variable where the USSD response will be stored (e.g. [[vars.input]]).
          - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
            - `type` 'webhook', required: Action type identifier
            - `url` string, required: Webhook URL to receive the HTTP POST request.
            - `secret` string: Secret string passed as POST parameter for request verification.
            - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
              - …
  - ServiceConfigMessageStatusActions: Configuration for `message_status_actions` service type.
    - `actions` MessageStatusAction[]: Array of actions to execute. Each action is an object with a `type` property and additional properties depending on the action type. See <a href="/api/rules_engine#actions">Action Reference</a> for documentation of available action types.
      - union: An action available for `message_status_actions` service type.
        - object: Within a service triggered when a message status changes, will automatically resend the current message via the same route or a different route.
          - `type` 'resend_message', required: Action type identifier
          - `route_id` string: ID of the route to resend the message from. If not specified, uses the original route.
          - `schedule` object: Schedule for when to resend the message. If not specified, resends immediately.
        - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
          - `type` 'add_contact_to_group', required: Action type identifier
          - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
        - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
          - `type` 'remove_contact_from_group', required: Action type identifier
          - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
        - object: Updates custom contact information for the current contact (for example, email address or birthdate). The rules editor lists the current variable names available for your project. You can also use a new variable name consisting of letters, numbers, and underscores.
          - `type` 'set_contact_var', required: Action type identifier
          - `variable` string, required: Name of the contact variable to set (without the contact.vars prefix).
          - `value` string: Value to assign to the variable.
        - object: Blocks the current contact.
          - `type` 'block_contact', required: Action type identifier
          - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
        - object: Sends a plain-text email with custom subject line and body. Each rule can only send to a single email address; if you need multiple recipients, we recommend setting up a mailing list on your own server. When receiving MMS and chat messages, you can optionally send the multimedia files as email attachments. To prevent abuse, it isn't possible to change the 'From' name or email address of the email, although these settings can be configured when using Telerivet on a custom domain.
          - `type` 'send_email', required: Action type identifier
          - `to_email` string, required: Recipient email address.
          - `subject` string, required: Email subject line.
          - `body_text` string, required: Email body text.
          - `reply_to` string: Reply-to email address.
          - `include_message_attachments` boolean: If true, include any attachments from the current message as email attachments.
        - object: Adds a label to the current message. This makes it easy to segment certain types of messages on your Messages page.
          - `type` 'add_label_to_message', required: Action type identifier
          - `label_name` string, required: Name of the label to add to the message.
        - object: Adds a star to the current message. This makes it easy to segment important messages on your Messages page.
          - `type` 'star_message', required: Action type identifier
        - object: Updates the value of any writable variable within the Rules Engine. Optionally, you can use this rule to perform simple numeric operations between two variables such as addition, subtraction, multiplication and division. Read-only variables cannot be updated via this rule. [See available variables](#message_variables)
          - `type` 'set_variable', required: Action type identifier
          - `variable` string, required: Name of the variable to set (e.g. $foo, contact.vars.bar, phone.vars.baz).
          - `value` string, required: Value to assign to the variable.
          - `op` 'plus' | 'minus' | 'times' | 'div': Optional arithmetic operation to perform between value and value2.
          - `value2` string: Second operand for the arithmetic operation (required if op is specified).
        - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
          - `type` 'cancel_scheduled_messages', required: Action type identifier
        - object: Makes a HTTP POST request to a URL on your server, passing several POST parameters with information about the current message and contact. Your webhook script may optionally return a JSON response with a 'messages' property containing an array of messages to send, and a 'variables' property containing variable names and values to update. For details, see the [Webhook API documentation](/api/webhook).
          - `type` 'webhook', required: Action type identifier
          - `url` string, required: Webhook URL to receive the HTTP POST request.
          - `secret` string: Secret string passed as POST parameter for request verification.
          - `params` object[]: Custom POST parameters to include in the webhook request, in addition to the standard parameters (max 20). A custom parameter with the same name as a standard parameter (including <code>secret</code>) takes precedence over the standard value.
            - `name` string, required: POST parameter name (max 100 characters).
            - `value` string, required: Parameter value. May contain [[variables]].
        - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
          - `type` 'log', required: Action type identifier
          - `value` string, required: Log message content.
        - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
          - `type` 'condition', required: Action type identifier
          - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
            - `type` string, required: Condition type. Values: <code>is</code>, <code>is_not</code>, <code>has_word</code>, <code>does_not_have_word</code>, <code>contains</code>, <code>does_not_contain</code>, <code>starts_with</code>, <code>does_not_start_with</code>, <code>ends_with</code>, <code>does_not_end_with</code>, <code>alpha_before</code>, <code>alpha_after</code>, <code>equals</code>, <code>does_not_equal</code>, <code>less_than</code>, <code>greater_than</code>, <code>less_or_equal</code>, <code>greater_or_equal</code>, <code>contact_is_in_group</code>, <code>contact_not_in_group</code>.
            - `variable` string, required: Variable to test, e.g. <code>[[word1]]</code>, <code>[[contact.name]]</code>. Not required for <code>contact_is_in_group</code> and <code>contact_not_in_group</code> conditions.
            - `value` string, required: Value to compare against (or group name for group membership conditions).
          - `actions` Action[], required: Array of actions to execute if the conditions match.
            - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
              - …
          - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
          - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
        - object: Stops processing rules for this message (for this service only).
          - `type` 'stop', required: Action type identifier
        - object: Copies the current incoming message to another project within the same organization. This is useful for routing messages to different projects based on message content or contact information, while keeping the original message in the current project.
          - `type` 'copy_message_to_project', required: Action type identifier
          - `project_id` string, required: ID of the project to copy the message to. Must be a project within the same organization.
        - object: Updates a custom variable for the current message. When triggered from a service that has a response data table (such as a poll service or custom actions with response handlers), custom message variables set via this action are automatically copied as custom variables on the corresponding response data table row. This is the recommended way to store derived or computed values in the response data table.
          - `type` 'set_message_var', required: Action type identifier
          - `variable` string, required: Name of the message variable to set (without the vars prefix).
          - `value` string: Value to assign to the variable.
        - object: Triggers a set of actions which can be reused multiple times in the same service.
          - `type` 'run_subroutine', required: Action type identifier
          - `name` string, required: Name of the subroutine to run.
        - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
          - `type` 'run_script', required: Action type identifier
          - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
        - object: Triggers another service for the current contact.
          - `type` 'trigger_contact_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
          - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
          - `schedule` object: Schedule for when to trigger the service. If not specified, triggers the service immediately.
        - object: Triggers another service for the current message.
          - `type` 'trigger_message_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
          - `route_id` string: ID of the route to use as the default route for messages sent by the triggered service. If not specified, uses the current default route.
        - object: Triggers another service for the current project.
          - `type` 'trigger_project_service', required: Action type identifier
          - `service_id` string, required: ID of the service to trigger.
    - `subroutines` object[]: Array of subroutine definitions. Subroutines are reusable sets of actions that can be called from the main actions or other subroutines.
      - `name` string, required: Unique name for the subroutine (max 32 characters).
      - `context` string: Context type for the subroutine. If not specified, defaults to the service's context.
      - `actions` Action[], required: Array of actions to execute when the subroutine is called. Available actions depend on the subroutine's context.
        - union: An action in a Custom Actions service. The `type` property determines which action is performed and what additional properties are available. See [Rules Engine Actions](/api/rules_engine#actions) for detailed documentation.
          - object: Adds the current contact to a group. If the group doesn't exist yet, Telerivet will create it. If you want to add a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'add_contact_to_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Adds a label to the current message. This makes it easy to segment certain types of messages on your Messages page.
            - `type` 'add_label_to_message', required: Action type identifier
            - `label_name` string, required: Name of the label to add to the message.
          - object: Blocks the current contact.
            - `type` 'block_contact', required: Action type identifier
            - `send_blocked` boolean: If true, block sending messages to this contact. If false, unblock the contact. Default: true.
          - object: Sends a voice call to the current contact using a specified IVR service.
            - `type` 'call_contact', required: Action type identifier
            - `service_id` string, required: ID of the voice/IVR service to use for the call.
            - `route_id` string: ID of the route to use for the call. If not specified, uses the default route.
            - `schedule` object: Schedule for when to make the call. If not specified, calls immediately.
          - object: Cancels all scheduled messages to the current contact. Note this doesn't cancel messages that are scheduled to an entire group. In this case, the contact would need to be removed from the group in order to cancel the message.
            - `type` 'cancel_scheduled_messages', required: Action type identifier
          - object: A rule that only matches if a certain condition is true (e.g. the message has a particular keyword or sender). Always combined with one or more other rules. "If ... then ..." rules can use the following types of conditions: * is * is not * has word * does not have word * contains * does not contain * starts with * does not start with * ends with * does not end with * alphabetically before * alphabetically after * equals * does not equal * less than * greater than * less than or equal to * greater than or equal to * contact is in group * contact is not in group A single "If ... then ..." rule can contain multiple conditions, joined together with either 'and' or 'or'.
            - `type` 'condition', required: Action type identifier
            - `conditions` object[]: Array of condition objects. Required unless <code>if_mode</code> is <code>else</code>.
              - …
            - `actions` Action[], required: Array of actions to execute if the conditions match.
            - `op` string: Operator to join multiple conditions. Values: <code>and</code> (all conditions must match), <code>or</code> (any condition must match). Default: <code>or</code>.
            - `if_mode` string: Controls how this condition relates to previous conditions. Values: <code>if</code> (default, starts a new conditional block), <code>else_if</code> (only evaluated if the previous <code>if</code> or <code>else_if</code> did not match), <code>else</code> (executed if none of the previous <code>if</code>/<code>else_if</code> conditions matched; does not require <code>conditions</code> array).
          - object: Copies the current incoming message to another project within the same organization. This is useful for routing messages to different projects based on message content or contact information, while keeping the original message in the current project.
            - `type` 'copy_message_to_project', required: Action type identifier
            - `project_id` string, required: ID of the project to copy the message to. Must be a project within the same organization.
          - object: Ends the current USSD session.
            - `type` 'end_session', required: Action type identifier
          - object: Within a poll service, skips to the end of the survey.
            - `type` 'end_survey', required: Action type identifier
          - object: Forwards the incoming call to another phone number.
            - `type` 'forward_call', required: Action type identifier
            - `phone_number` string, required: Phone number to forward the call to.
          - object: Hangs up the phone call.
            - `type` 'hangup', required: Action type identifier
          - object: Within a poll service, ignores the current message.
            - `type` 'ignore_message', required: Action type identifier
          - object: Adds a log message to Telerivet's [service log](/dashboard/service_logs). To view the service log, open your [Services page](/dashboard/services) and click More > View logs. When using the "Test Service" feature, log messages will be displayed directly in the simulated phone dialog.
            - `type` 'log', required: Action type identifier
            - `value` string, required: Log message content.
          - object: Plays an audio file in WAV or MP3 format in the voice call, which may be uploaded, linked, or recorded via the Telerivet web app. Alternatively, can use text-to-speech to speak a message.
            - `type` 'play_audio', required: Action type identifier
            - `mode` 'file' | 'tts', required: Audio source mode.
            - `audio_url` string: URL of the audio file to play (WAV or MP3). Required when mode is "file".
            - `audio_title` string: Title for the audio file displayed in the web app (not played to the caller). Used when mode is "file".
            - `text` string: Text to speak using text-to-speech. Required when mode is "tts". If mode is "file", the text is not used in the actual call but is displayed as the transcript of the file within the web app.
            - `language` string: Language code for text-to-speech (e.g., "en-US"). Used when mode is "tts".
            - `voice` string: Voice for text-to-speech (e.g., "man", "woman"). Used when mode is "tts".
            - `repeat` boolean: If true, repeat the audio once after a short pause.
          - object: Pushes the message to a HubSpot Help Desk inbox, in a conversation associated with the current contact. HubSpot agents can reply directly to send a reply to the contact.
            - `type` 'push_to_hubspot', required: Action type identifier
            - `integration_id` string, required: ID of the HubSpot channel integration config.
            - `content` string: Content of the message pushed to HubSpot.
          - object: Pushes the message to a Zendesk support inbox, in a ticket associated with the current contact. Zendesk agents can reply directly to the Zendesk ticket to send a reply to the contact.
            - `type` 'push_to_zendesk', required: Action type identifier
            - `subdomain` string, required: Zendesk subdomain (e.g., "example" for example.zendesk.com).
            - `subject` string, required: Subject line for the Zendesk ticket.
            - `content` string, required: Content of the Zendesk ticket.
          - object: Records an audio response from the caller, saves the recording URL as a custom variable on the message, then triggers the associated response handler.
            - `type` 'record_audio', required: Action type identifier
            - `state_id` string, required: ID of the response handler that will be triggered when the recording is received (e.g., "recording"). Also used as the name of the variable where the recording URL will be stored (e.g. [[vars.recording]]).
          - object: Removes the current contact from a group. If you want to remove a contact other than the one who sent the message, add a "Use another contact" rule before this rule.
            - `type` 'remove_contact_from_group', required: Action type identifier
            - `group_name` string, required: Name of the group. If the group does not exist, it will be created.
          - object: Within a poll service, repeats the current question again.
            - `type` 'repeat_question', required: Action type identifier
          - object: Sends a text reply to the sender. Optionally, the reply can be scheduled after a predefined delay, or sent via a different phone than the one that received the message.
            - `type` 'reply', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `route_id` string: ID of the route to send the message from. If not specified, uses the default route.
            - `label_names` string[]: Array of label names to apply to the sent message.
            - `schedule` object: Schedule to send the message at a later time.
            - `on_click` string: Name of a subroutine (with context `message`) to run the first time the recipient clicks a link in the message. Requires `body.track_clicks`. Within the subroutine, [[$destination_url]] is the URL that was clicked.
            - `on_click_timeout` object: Runs a subroutine (with context `message`) if the recipient has not clicked a link in the message within the specified time. Requires `body.track_clicks`.
          - object: Sends a text reply to the sender (simple version without labels, schedule, or route configuration).
            - `type` 'reply_simple', required: Action type identifier
            - `body` MessageBodyWithVariants, required
              - …
            - `schedule` object: Schedule to send the message at a later time.
          - object: Within a service triggered when a message status changes, will automatically resend the current message via the same route or a different route.
            - `type` 'resend_message', required: Action type identifier
            - `route_id` string: ID of the route to resend the message from. If not specified, uses the original route.
            - `schedule` object: Schedule for when to resend the message. If not specified, resends immediately.
          - object: Runs custom JavaScript code on Telerivet's servers using Telerivet's Cloud Script API. This makes it possible to define custom actions such as calling the Telerivet REST API or third-party APIs, or parsing structured data from incoming messages. For more details, see the [Cloud Script API documentation](/api/script).
            - `type` 'run_script', required: Action type identifier
            - `code` string, required: JavaScript code to execute. See <a href="https://telerivet.com/api/script">Cloud Script API</a> for available functions and variables.
          - object: Triggers a set of actions which can be reused multiple times in the same service.
            - `type` 'run_subroutine', required: Action type identifier
            - `name` string, required: Name of the subroutine to run.
- … truncated; see the full OpenAPI document linked below

## Other responses

- `400`: Invalid request parameters
- `401`: Invalid or missing API key or Bearer token
- `404`: Resource not found

---

[API](https://skmtc.dev/telerivet/apis/telerivet-api.md) · [All operations](https://skmtc.dev/telerivet/apis/telerivet-api/llms.txt) · [OpenAPI document](https://skmtc.dev/telerivet/apis/telerivet-api/revisions/4e14b1c8d917?raw)
