# RevCent MCP Operation: `EditFunction`

This document describes the `EditFunction` MCP operation, every input field from the operation schema, and the practical Function configuration rules from the RevCent Functions knowledge base.

Sources used:
- RevCent MCP operation schema for `EditFunction`
- RevCent Knowledge Base / product documentation: Functions — `https://kb.revcent.com/en/integrations/functions`
- RevCent Knowledge Base / product documentation: Key Values — `https://kb.revcent.com/en/tools/key-value`

> Scope: This document intentionally covers only the `EditFunction` operation.

---

## Operation Summary

`EditFunction` edits a previously created RevCent Function using its 20-character `function_id`.

Use `EditFunction` after `CreateFunction` to configure or modify:

- Function name and description.
- Enabled status.
- JavaScript function code.
- Event source / trigger type.
- Account event trigger notations.
- Account event filters.
- Account event timing options.
- Schedule cron expression and timezone.
- Dependencies.
- Environment variables.
- Function URL / webhook IP restrictions.
- API/AI custom arguments.
- Function code usage of Key Values for shared configuration or state management.

Important edit behavior:

- `function_id` is required.
- Only include properties you want to modify.
- Omitted fields remain unchanged.
- Some array fields replace the existing values when provided.
- `environment_variables` are upserted, not fully replaced.
- `dependencies` replace the existing dependency list when provided.
- `custom_arguments` replace the existing custom argument list when provided.

---

## Required Fields

The `EditFunction` schema requires only:

| Field | Type | Required | Notes |
|---|---:|---:|---|
| `function_id` | string | Yes | 20-character Function ID to edit. |

All other fields are optional and should only be included when you want to modify them.

---

## Complete Input Schema Field Reference

### `function_id`

**Type:** `string`  
**Required:** Yes  
**Length:** 20 characters

The ID of the Function being edited.

```json
"function_id": "XXXXXXXXXXXXXXXXXXXX"
```

Important behavior:

- This is the only required field.
- It identifies the existing Function to update.
- Do not include unrelated fields unless you intend to change them.

---

### `name`

**Type:** `string`  
**Required:** No

The Function name.

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "name": "Slack Alert - Chargeback Created"
}
```

Important behavior:

- Must be unique from other Function names.
- Omit this field if the name should remain unchanged.

Recommended naming pattern:

```text
<Trigger or Source> - <Action or Destination> - <Purpose>
```

Examples:

```text
Account Event - Slack Alert - Chargeback Created
Email Template - Custom Data - Receipt Personalization
Schedule - Daily Report - Revenue Summary
API Direct - Normalize Payload - Partner Webhook
```

---

### `description`

**Type:** `string`  
**Required:** No

The Function description.

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "description": "Posts a message to Slack when a chargeback is created."
}
```

Recommended content:

- Trigger or event source.
- External systems involved.
- Important inputs.
- Expected output.
- Required dependencies.
- Required environment variables.
- Whether the Function is for API/AI, account events, email templates, schedules, URLs, payment profiles, or another source.

---

### `enabled`

**Type:** `boolean`  
**Required:** No

Whether the Function is enabled.

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "enabled": true
}
```

Behavior:

- `true`: the Function can run when triggered.
- `false`: the Function should not run.
- Use `false` while drafting or testing configuration.
- Omit this field if enabled status should remain unchanged.

---

### `function_code`

**Type:** `string`  
**Required:** No

The JavaScript code of the Function.

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "function_code": "callback(null, { success: true });"
}
```

## Important: Do Not Include the Execution Handler Wrapper

RevCent already wraps Function code in an execution handler that provides:

```javascript
event
context
callback
```

That means the code submitted in `function_code` should be only the body of the Function. Do **not** include your own wrapper such as:

```javascript
exports.handler = async (event, context, callback) => {
  // Do not include this wrapper
};
```

Do **not** submit this:

```javascript
module.exports = async function(event, context, callback) {
  callback(null, { success: true });
};
```

Do **not** submit this:

```javascript
async function handler(event, context, callback) {
  callback(null, { success: true });
}
```

Submit only the inner Function logic:

```javascript
callback(null, {
  success: true,
  message: "Function completed."
});
```

Important requirements:

- The Function code is already inside a handler with `event`, `context`, and `callback` available.
- A callback must be called within the function code to end each invocation.
- Use `callback(error, response)` to complete execution.
- If the Function does not call the callback, the invocation may not end correctly.
- Do not define or export a handler.
- Do not wrap the code in `exports.handler`, `module.exports`, or a custom `handler(...)` function.
- Confirm the execution handler behavior in the Functions KB before deployment.

Basic successful response:

```javascript
callback(null, {
  success: true,
  message: "Function completed."
});
```

Basic error response:

```javascript
callback(new Error("Missing required input."));
```

Recommended error handling:

```javascript
try {
  // Function logic here
  callback(null, {
    success: true
  });
} catch (error) {
  callback(error);
}
```

---

## `event_source`

**Type:** `string` enum  
**Required:** No

Determines how the Function is triggered, meaning how the code is executed.

Allowed values:

```text
account_event
api_direct
email_template
payment_profile
function_url
schedule
```

> Note: The operation description mentions URL and Webhook as trigger options. In the schema enum, the URL/webhook-style external request source is represented by `function_url`.

---


# Detailed Event Source and Event Body Reference

Every Function trigger type provides a different `event` payload shape to the Function runtime.

RevCent already injects these runtime variables into the Function body:

```javascript
event
context
callback
```

Do not define your own handler wrapper.

Use the event-body JSON link for the configured trigger type as the source of truth for the runtime payload.

---

## `account_event`

### Event Body JSON

Account-event Functions use an event body JSON determined by the first word in the account event notation.

Pattern:

```text
https://revcent.com/documentation/files/function/event/account_event/<item_type>.json
```

Examples:

| Account Event Notation | Item Type | Event Body JSON |
|---|---|---|
| `sale.created.success` | `sale` | https://revcent.com/documentation/files/function/event/account_event/sale.json |
| `customer.created` | `customer` | https://revcent.com/documentation/files/function/event/account_event/customer.json |
| `shipping.updated.shipped` | `shipping` | https://revcent.com/documentation/files/function/event/account_event/shipping.json |
| `subscription.updated.renewed.success` | `subscription` | https://revcent.com/documentation/files/function/event/account_event/subscription.json |
| `subscription_renewal.updated.success` | `subscription_renewal` | https://revcent.com/documentation/files/function/event/account_event/subscription_renewal.json |
| `trial.updated.expired.success` | `trial` | https://revcent.com/documentation/files/function/event/account_event/trial.json |

### Runtime Event Structure

Account-event Functions generally receive:

```javascript
event.data.item_type
event.data.item_id
event.data.item_details
```

Example:

```javascript
let item = event.data.item_details;

callback(null, {
  customer_email: item.customer.email
});
```

### Typical Use Cases

- Sales notifications.
- Fraud alerts.
- Subscription lifecycle processing.
- Shipping updates.
- Customer-change processing.
- CRM synchronization.
- Slack alerts.

### Best Practices

- Use the most specific notation available.
- Validate required nested properties before use.
- Expect different payload structures depending on item type.
- Use the linked event-body JSON as the source of truth.

---

## `api_direct`

### Event Body JSON

Primary API-direct event body:

https://revcent.com/documentation/files/function/event/api_direct.json

> Note: the CDN URL may return a restricted response depending on retrieval method, but this is still the documented payload reference.

### Runtime Event Structure

API-direct Functions can be triggered explicitly through API/MCP, AI tool execution, or used as filter functions in AI Assistants and AI Voice Agents.

Typical runtime values for direct triggering may include:

```javascript
event.data
event.data.custom_arguments
event.data.item_type
event.data.item_id
event.data.item_details
```

depending on how the Function is triggered.

### API Direct as an AI Assistant / AI Voice Agent Filter Function

An `api_direct` Function can also be used as a filter Function for:

- AI Assistants
- AI Voice Agents

When used as a filter Function, the event body is based on the `item_type` and `item_id` being evaluated. This is similar to an `account_event` event body, except account-event notations are not present.

Filter Function event body URL pattern:

```text
https://revcent.com/documentation/files/function/event/filter/<item_type>.json
```

Examples:

| Filter item type | Filter Function event body JSON |
|---|---|
| `sale` | https://revcent.com/documentation/files/function/event/filter/sale.json |
| `customer` | https://revcent.com/documentation/files/function/event/filter/customer.json |
| `shipping` | https://revcent.com/documentation/files/function/event/filter/shipping.json |
| `subscription` | https://revcent.com/documentation/files/function/event/filter/subscription.json |
| `subscription_renewal` | https://revcent.com/documentation/files/function/event/filter/subscription_renewal.json |
| `trial` | https://revcent.com/documentation/files/function/event/filter/trial.json |

Common filter Function paths:

```javascript
event.data.item_type
event.data.item_id
event.data.item_details
```

Because notations are not present, do not rely on:

```javascript
event.data.event_notations
```

unless the specific payload explicitly contains it.

### Filter Function Return Value

When an `api_direct` Function is used as a filter Function for AI Assistants or AI Voice Agents, it should return a single term:

```javascript
callback(null, "pass");
```

or:

```javascript
callback(null, "fail");
```

Meaning:

- `pass`: allow the AI Assistant or AI Voice Agent to proceed.
- `fail`: prevent the AI Assistant or AI Voice Agent from proceeding for that item.

### Typical Use Cases

- AI tool execution.
- Manual API-triggered workflows.
- Payload transformation.
- External system orchestration.
- On-demand reporting.
- AI Assistant filtering.
- AI Voice Agent filtering.
- Item-specific eligibility checks before an AI run or call.

### Best Practices

- Define clear `custom_arguments` for normal API-direct triggering.
- Validate every expected argument.
- Fail clearly when arguments are missing.
- Do not assume item context exists unless supplied.
- For filter usage, use the filter event body URL matching the `item_type`.
- For filter usage, do not include or rely on `custom_arguments`.
- For filter usage, return only `"pass"` or `"fail"`.
- For filter usage, do not rely on account-event notations.

---

## `payment_profile`

### Event Body JSON

https://revcent.com/documentation/files/function/event/payment_profile.json

### Applies To

`payment_profile` Functions run from a **Run Function** action node inside a Next-Gen Payment Profile flow.

KB reference:

https://kb.revcent.com/payments/credit-card/next-gen-payment-profile#run-function

A Run Function node can operate in two different run methods:

| Run Method | Behavior |
|---|---|
| `Queue And Continue` | The Function runs separately. RevCent does not wait for a response. The payment flow continues through the green output of the Run Function node. |
| `Wait For Response` | RevCent waits for the Function response. The response can determine the next node, output path, gateway choice, or custom error. |

Important warnings for `Wait For Response`:

- Route the red output as a backup in case the Function fails or times out.
- The Function has a maximum of 8 seconds to respond within the flow.
- Bad Function code can prevent payments from being processed.
- Functions add latency to the payment response.
- Use this only when you fully understand the Next-Gen payment flow.

---

### Runtime Event Structure

Payment-profile Functions receive the current payment flow request in `event.data`.

The item details of the payment request are contained in:

```javascript
event.data.item_details
```

Top-level event paths:

```javascript
event.data.item_type
event.data.item_id
event.data.item_event
event.data.item_details
```

Common payment-profile paths:

```javascript
event.data.item_details.request
event.data.item_details.entity
event.data.item_details.customer
event.data.item_details.customer_card
event.data.item_details.campaign
event.data.item_details.payment_profile
event.data.item_details.payment_amount
event.data.item_details.products
event.data.item_details.shipping
event.data.item_details.tax
event.data.item_details.gateway_history
event.data.item_details.node_id
event.data.item_details.next_nodes
event.data.item_details.current_step
event.data.item_details.step_array
event.data.item_details.flow_path
```

### Event Body Key Fields

| Field | Type | Description |
|---|---:|---|
| `event.data.item_type` | string | The item type being processed, such as `sale`. |
| `event.data.item_id` | string | The item ID being processed. |
| `event.data.item_event` | string | The event for the payment flow request, such as `payment_request`. |
| `event.data.item_details.request` | object | Details about the payment request. For initial sale requests, this can include metadata sent in the API call. |
| `event.data.item_details.entity` | object | The entity related to the request. For an initial sale this is the sale; for subscription renewal this relates to the subscription and may include a subscription renewal sub-item. |
| `event.data.item_details.customer` | object | Customer details related to the request. |
| `event.data.item_details.customer_card` | object | Customer card details related to the request, including card type, first 6, and BIN details when available. |
| `event.data.item_details.campaign` | object | Campaign details related to the request. |
| `event.data.item_details.payment_profile` | object | Payment Profile details related to the request. |
| `event.data.item_details.payment_amount` | number | The amount being processed by the flow request. |
| `event.data.item_details.products` | array | Product objects specific to the payment flow request. |
| `event.data.item_details.shipping` | array | Shipping objects specific to the payment flow request. |
| `event.data.item_details.tax` | array | Tax objects specific to the payment flow request. |
| `event.data.item_details.gateway_history` | object | Gateway and gateway-group history for the current request, customer, entity, and gateway group. |
| `event.data.item_details.node_id` | string | The current Run Function node ID. |
| `event.data.item_details.next_nodes` | object | Nodes connected to the Run Function node outputs. Useful when returning `next_node_id`. |
| `event.data.item_details.current_step` | integer | The current payment flow step being processed. |
| `event.data.item_details.step_array` | array | Current and previous payment attempt steps. Useful for deciding what to do after declines. |
| `event.data.item_details.flow_path` | array | Ordered list of nodes processed so far and their results. |

### Gateway History

`gateway_history` is especially important for routing logic.

Common paths:

```javascript
event.data.item_details.gateway_history.current.declined
event.data.item_details.gateway_history.customer.approved
event.data.item_details.gateway_history.customer.approved_cvv
event.data.item_details.gateway_history.customer.declined
event.data.item_details.gateway_history.customer.declined_cvv
event.data.item_details.gateway_history.entity.approved
event.data.item_details.gateway_history.entity.approved_cvv
event.data.item_details.gateway_history.entity.declined
event.data.item_details.gateway_history.entity.declined_cvv
event.data.item_details.gateway_history.gateway_group.approved
event.data.item_details.gateway_history.gateway_group.approved_cvv
event.data.item_details.gateway_history.gateway_group.declined
event.data.item_details.gateway_history.gateway_group.declined_cvv
```

Use this data to decide:

- Whether to retry a gateway.
- Whether to avoid a gateway.
- Whether to choose a gateway group.
- Whether the customer or entity has prior approvals or declines.
- Whether CVV-passed history should influence routing.

---

## Payment Profile Function Response

If the Run Function node is configured with `Queue And Continue`, the Function response is not used to control the payment flow.

If the Run Function node is configured with `Wait For Response`, the Function should return a response object using:

```javascript
callback(null, {
  // response properties here
});
```

If no properties are returned, RevCent treats the Run Function node as passed and follows the green output without taking additional action.

Only return the properties needed for the desired action.

### Response Object Shape

```javascript
callback(null, {
  next_node_id: "43965f05-887a-4e70-8646-0410440a3494",
  next_output: "1",
  set_gateway_id: "bOLjn0yvKpUp10qK298R",
  selection_method: "evenly_distribute",
  choose_gateways: ["2r7zOBMldVIomKNdKZoG"],
  choose_gateway_groups: ["GOGaPRql9oUAAkrm5Ll9"],
  custom_error: "Card CVV Invalid"
});
```

### Response Fields

| Field | Type | Description |
|---|---:|---|
| `next_node_id` | string | Routes to a specific next node connected to the Run Function node output. Use `event.data.item_details.next_nodes.actions` or `event.data.item_details.next_nodes.filters` to determine available nodes. |
| `next_output` | string | Chooses the Run Function node output path. `1` is green output; `2` is red output. |
| `set_gateway_id` | string | Sets a specific gateway as the current step gateway for payment processing. A Process Payment node must be in the output path for payment to process. |
| `selection_method` | string | Overrides the next Choose Gateway node's selection method when used with `choose_gateways` or `choose_gateway_groups`. Common values include `evenly_distribute`, `round_robin`, and `random`. |
| `choose_gateways` | array<string> | Overrides a next Choose Gateway node's gateway selections with the provided gateway IDs. |
| `choose_gateway_groups` | array<string> | Overrides a next Choose Gateway node's gateway group selections with the provided gateway group IDs. |
| `custom_error` | string | Provides a custom error response for a following Abort Flow node. Must also return a `next_node_id` pointing to an Abort Flow node. |

### Response Examples

#### Pass Through Green Output

```javascript
callback(null, {});
```

or:

```javascript
callback(null, {
  next_output: "1"
});
```

#### Route Through Red Output

```javascript
callback(null, {
  next_output: "2"
});
```

#### Route to a Specific Node

```javascript
callback(null, {
  next_node_id: "43965f05-887a-4e70-8646-0410440a3494"
});
```

#### Set a Gateway and Route to Process Payment

```javascript
callback(null, {
  set_gateway_id: "bOLjn0yvKpUp10qK298R",
  next_node_id: "f96f16ba-2cab-4ae5-9932-4f548cd479ba"
});
```

#### Override Gateway Choices

```javascript
callback(null, {
  selection_method: "random",
  choose_gateways: ["2r7zOBMldVIomKNdKZoG"],
  next_node_id: "43965f05-887a-4e70-8646-0410440a3494"
});
```

#### Abort with a Custom Error

```javascript
callback(null, {
  next_node_id: "0b8a520e-a74e-4516-8a5b-807337687847",
  custom_error: "Card CVV Invalid"
});
```

Important:

- The `next_node_id` should point to a following Abort Flow node when using `custom_error`.
- The shopping cart or API client must be able to parse and display custom errors correctly.
- Custom error behavior depends on whether payment was attempted.

### Typical Use Cases

- Payment routing.
- Gateway decisioning.
- Fraud checks.
- Payment orchestration.
- Custom decline handling.
- Gateway response parsing.
- Custom transaction logic.
- Custom payment error messages.
- Routing after failed gateway attempts.
- Choosing gateways based on customer, entity, or gateway history.

### Best Practices

- Keep execution fast because payment flows are time-sensitive.
- For `Wait For Response`, always design for the 8-second timeout.
- Always connect the red output to a safe fallback route.
- Validate customer, card, gateway, and payment objects before use.
- Avoid long-running external requests.
- Use environment variables for secrets.
- Handle retry-safe logic carefully.
- Return only the response properties needed.
- Use `Queue And Continue` if the Function does not need to control the flow.
- Use `Wait For Response` only when the Function response must determine the next action.

---

## `function_url`

### Event Body JSON

https://revcent.com/documentation/files/function/event/function_url.json

### Runtime Event Structure

Function URL triggers receive inbound request data.

Example payload:

```json
{
  "data": "{\"test\": \"urltest\"}"
}
```

### Typical Use Cases

- Partner integrations.
- Lightweight inbound APIs.
- Form receivers.
- External callbacks.
- Internal utility endpoints.

### Best Practices

- Validate inbound payloads.
- Authenticate requests where possible.
- Use IP restriction when appropriate.
- Expect arbitrary user input.

---

## `webhook`

### Event Body JSON

https://revcent.com/documentation/files/function/event/webhook.json

### Runtime Event Structure

Webhook triggers receive POST request data.

Example payload:

```json
{
  "data": "{\"test\": \"webhooktest\"}"
}
```

### Typical Use Cases

- External webhook ingestion.
- Third-party notifications.
- Partner callback processing.
- Event-forwarding systems.

### Best Practices

- Verify signatures or secrets when possible.
- Prevent duplicate processing.
- Return fast responses.
- Store important payloads safely.

---

## `schedule`

### Event Body JSON

https://revcent.com/documentation/files/function/event/schedule.json

### Runtime Event Structure

Scheduled Functions typically receive a minimal payload.

Example:

```json
{
  "data": ""
}
```

### Typical Use Cases

- Daily reports.
- Scheduled cleanup.
- Batch synchronization.
- Periodic API syncs.
- Maintenance jobs.

### Best Practices

- Build idempotent jobs.
- Handle empty payloads.
- Avoid assuming only one execution can occur at a time.
- Log execution checkpoints where appropriate.

---

## `pre_agent`

### Event Body JSON

https://revcent.com/documentation/files/function/event/pre_agent.json

### Applies To

`pre_agent` Functions are specifically for **AI Voice Agents**. They run immediately before an AI Voice Agent is initiated for a call.

The purpose of a pre-agent Function is to generate custom data that can be used inside AI Voice Agent instructions with Handlebars.

KB reference:

https://kb.revcent.com/en/tools/ai/voice-agents#pre-agent-function

### Runtime Event Structure

A pre-agent Function receives the item details related to the call, plus call/agent context.

Common paths include:

```javascript
event.data.item_type
event.data.item_id
event.data.item_details
```

The provided example payload contains a full Customer object in `event.data.item_details`.

Pre-agent Functions may run for different AI Voice Agent call scenarios:

| AI Voice Agent scenario | Event body behavior |
|---|---|
| Inbound call with customer phone match | Receives customer item context. |
| Inbound call without customer phone match | May receive an empty object. |
| Outbound call from event trigger | Receives event notation plus item context, such as sale/customer/shipping data. |
| Outbound call from on-demand trigger | Receives the supplied item type, item ID, and populated item details. |

### Return Value and Handlebars Usage

The pre-agent Function should return a plain JSON object through `callback(null, responseObject)`.

Example Function code body:

```javascript
callback(null, {
  company_name: "Acme Inc.",
  allow_full_refunds: false,
  product_list: [
    {
      name: "Product A",
      price: 29.99
    }
  ]
});
```

The response is made available to AI Voice Agent instruction Handlebars under:

```handlebars
{{pre_agent_function.response.company_name}}
{{pre_agent_function.response.allow_full_refunds}}
{{{toString pre_agent_function.response.product_list}}}
```

## AI Voice Agent Pre-Agent Function Response Object

The AI Voice Agent instructions Handlebars data includes a `pre_agent_function` object when a pre-agent Function is configured.

Response object shape:

```json
{
  "pre_agent_function": {
    "has_response": true,
    "response": {
      "company_name": "Acme Inc.",
      "allow_full_refunds": false
    }
  }
}
```

### `pre_agent_function.has_response`

**Type:** `boolean`

Indicates whether a pre-agent Function ran and returned a valid JSON object.

Use this when instructions should only reference response fields if the Function returned data.

```handlebars
{{#if pre_agent_function.has_response}}
Use the pre-agent function response below.
{{else}}
No pre-agent function response is available.
{{/if}}
```

### `pre_agent_function.response`

**Type:** `object`

The plain JSON object returned by the pre-agent Function.

Example Function body:

```javascript
callback(null, {
  company_name: "Acme Inc.",
  allow_full_refunds: false,
  product_list: [
    {
      name: "Product A",
      price: 29.99
    }
  ]
});
```

Example AI Voice Agent instruction usage:

```handlebars
{{#if pre_agent_function.response.company_name}}
- Identify as {{pre_agent_function.response.company_name}} customer support.
{{else}}
- Identify as customer support.
{{/if}}
```

For JSON objects or arrays, use the `toString` helper with triple braces:

```handlebars
# Available Products
{{{toString pre_agent_function.response.product_list}}}
```

Important:

- The Function should return a plain JSON object.
- The object is not inserted directly at the root of Handlebars data.
- It is available under `pre_agent_function.response`.
- Use stable key names because AI Voice Agent instructions reference these keys.
- Do not return sensitive secrets into the response object because the response may be included in AI instructions.

### Typical Use Cases

- Generate dynamic company or brand names for outbound calls.
- Build product lists to embed into voice-agent instructions.
- Add campaign-specific instructions.
- Add refund, escalation, or compliance rules.
- Enrich call instructions with external CRM data.
- Customize greetings or call objectives based on the call item.
- Provide structured JSON to the voice agent using the `toString` Handlebars helper.

### Best Practices

- Return a plain JSON object.
- Keep preprocessing fast so the voice call can start quickly.
- Validate nested item/customer properties before use.
- Handle inbound calls with no customer match.
- Do not return sensitive secrets into the instruction context.
- Avoid excessive external requests before agent execution.
- Use stable keys because AI Voice Agent instructions will reference them with Handlebars.

---

## `email_template`

### Event Body Relationship

Email-template Functions do not use a dedicated Function event-body file. Instead, they receive the same item context used by the Email Template trigger.

The related item details are commonly available at:

```javascript
event.data.item_details
```

The exact payload shape depends on the Email Template trigger.

Examples:

| Email Template Trigger | Source Input Data JSON |
|---|---|
| `sale_create_success` | https://revcent.com/documentation/files/email_template/input_data/sale.json |
| `customer_create_success` | https://revcent.com/documentation/files/email_template/input_data/customer.json |
| `subscription_renew_success` | https://revcent.com/documentation/files/email_template/input_data/subscription_renewal.json |

### Typical Use Cases

- Dynamic email personalization.
- Custom receipt content.
- AI-generated email snippets.
- Conditional email sections.
- External data enrichment for emails.

### Best Practices

- Return a plain JavaScript object.
- Keep payloads lightweight.
- Avoid circular references.
- Validate required nested paths before use.



# Event Source Reference

| `event_source` | Trigger behavior | Related fields |
|---|---|---|
| `account_event` | RevCent triggers the Function automatically when configured account events occur. | `account_event_notations`, `account_event_filters`, `timing_options` |
| `api_direct` | Function can be triggered via API/MCP or AI System Tool. It can also be used as a filter Function for AI Assistants and AI Voice Agents; filter payloads use `https://revcent.com/documentation/files/function/event/filter/<item_type>.json`. | `custom_arguments` only for direct triggering. Do not include `custom_arguments` for filter Function usage; filter usage uses item context and should return `pass` or `fail`. |
| `email_template` | Function generates `custom_data` for an Email Template. | `function_code`, environment/dependencies as needed |
| `payment_profile` | Function runs during Next-Gen payment profile processing. Event body: [`payment_profile.json`](https://revcent.com/documentation/files/function/event/payment_profile.json). | `function_code`, environment/dependencies as needed |
| `function_url` | Function is triggered by HTTP GET or POST request. | `ip_restricted`, `ip_whitelist` |
| `schedule` | Function runs on a fixed schedule using a cron expression. | `cron_expression`, `cron_timezone` |

---

## `account_event_notations`

**Type:** `array<string>`  
**Required:** No  
**Applies when:** `event_source` is `account_event`

Specifies one or more account event notations that trigger the Function.

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "event_source": "account_event",
  "account_event_notations": ["sale.created.success", "chargeback.created"]
}
```

When one of the configured account events occurs, RevCent triggers the Function.

For account event Functions, the event body JSON link is determined by the first word in the notation. For example, `sale.created` uses the `sale` account-event body file:

```text
https://revcent.com/documentation/files/function/event/account_event/sale.json
```

### Allowed Account Event Notations

```text
ai_memo.created
chargeback.created
check_direct.created
customer.created
customer.updated.add_card
customer.updated.address
customer.updated.customer_group
customer.updated.customer_group.added
customer.updated.customer_group.removed
customer.updated.disabled
customer.updated.enabled
discount.created
fraud_detection.created
fraud_detection.updated.false_positive
invoice.created
note.created
offline_payment.created
paypal_dispute.created
paypal_transaction.created
pending_refund.created
pending_refund.created.product_sale
pending_refund.created.product_sale.full
pending_refund.created.product_sale.partial
pending_refund.created.shipping
pending_refund.created.shipping.full
pending_refund.created.shipping.full.has_fulfillment
pending_refund.created.shipping.full.no_fulfillment
pending_refund.created.shipping.has_fulfillment
pending_refund.created.shipping.no_fulfillment
pending_refund.created.shipping.partial
pending_refund.created.shipping.partial.has_fulfillment
pending_refund.created.shipping.partial.no_fulfillment
pending_refund.created.subscription_renewal
pending_refund.created.subscription_renewal.full
pending_refund.created.subscription_renewal.partial
pending_refund.created.tax
pending_refund.created.tax.full
pending_refund.created.tax.partial
product.created
product.deleted
product.updated
product_sale.created
sale.created
sale.created.failed
sale.created.failed.declined
sale.created.failed.error
sale.created.failed.no_gateway
sale.created.failed.fraud_detected
sale.created.failed.merchant_error
sale.created.failed.merchant_hold
sale.created.success
sale.created.success.has_salvage
sale.created.success.is_upsell
sale.created.success.paid
sale.created.success.paid.has_salvage
sale.created.success.paid.is_upsell
sale.created.success.pending
sale.created.success.pending.is_upsell
sale.updated.fraud_alert.added
sale.updated.fraud_alert.removed
salvage_transaction.created
salvage_transaction.updated.processed
salvage_transaction.updated.processed.failed
salvage_transaction.updated.processed.success
sentinel.alert
sentinel.alert.fraud_detected
sentinel.alert.firewall_block
shipping.created
shipping.created.has_fulfillment
shipping.created.no_fulfillment
shipping.updated.delivered
shipping.updated.ship_to
shipping.updated.shipped
subscription.created
subscription.updated.renewed
subscription.updated.renewed.failed
subscription.updated.renewed.success
subscription.updated.status
subscription.updated.status.active
subscription.updated.status.cancelled
subscription.updated.status.occurrence_limit
subscription.updated.status.overdue
subscription.updated.status.suspended
subscription_renewal.updated.failed
subscription_renewal.updated.success
tax.created
transaction.created
trial.created
trial.updated.cancelled
trial.updated.expired
trial.updated.expired.failed
trial.updated.expired.success
trial.updated.extended
trial.updated.shortened
```


### Account Event Event JSON Links

Each account event notation maps to an account-event JSON body file based on the first word in the notation.

Pattern:

```text
https://revcent.com/documentation/files/function/event/account_event/<item_type>.json
```

Examples:

| Notation | First word / item type | Event JSON |
|---|---|---|
| `sale.created` | `sale` | [`sale.json`](https://revcent.com/documentation/files/function/event/account_event/sale.json) |
| `customer.created` | `customer` | [`customer.json`](https://revcent.com/documentation/files/function/event/account_event/customer.json) |
| `shipping.updated.shipped` | `shipping` | [`shipping.json`](https://revcent.com/documentation/files/function/event/account_event/shipping.json) |
| `subscription_renewal.updated.success` | `subscription_renewal` | [`subscription_renewal.json`](https://revcent.com/documentation/files/function/event/account_event/subscription_renewal.json) |

Use the linked JSON file as the source of truth for the `event` payload body when writing `function_code` for `account_event` Functions.

| Account event item type | Event JSON | Notations that use this event body |
|---|---|---|
| `ai_memo` | [`ai_memo.json`](https://revcent.com/documentation/files/function/event/account_event/ai_memo.json) | `ai_memo.created` |
| `chargeback` | [`chargeback.json`](https://revcent.com/documentation/files/function/event/account_event/chargeback.json) | `chargeback.created` |
| `check_direct` | [`check_direct.json`](https://revcent.com/documentation/files/function/event/account_event/check_direct.json) | `check_direct.created` |
| `customer` | [`customer.json`](https://revcent.com/documentation/files/function/event/account_event/customer.json) | `customer.created`, `customer.updated.add_card`, `customer.updated.address`, `customer.updated.customer_group`, `customer.updated.customer_group.added`, `customer.updated.customer_group.removed`, `customer.updated.disabled`, `customer.updated.enabled` |
| `discount` | [`discount.json`](https://revcent.com/documentation/files/function/event/account_event/discount.json) | `discount.created` |
| `fraud_detection` | [`fraud_detection.json`](https://revcent.com/documentation/files/function/event/account_event/fraud_detection.json) | `fraud_detection.created`, `fraud_detection.updated.false_positive` |
| `invoice` | [`invoice.json`](https://revcent.com/documentation/files/function/event/account_event/invoice.json) | `invoice.created` |
| `note` | [`note.json`](https://revcent.com/documentation/files/function/event/account_event/note.json) | `note.created` |
| `offline_payment` | [`offline_payment.json`](https://revcent.com/documentation/files/function/event/account_event/offline_payment.json) | `offline_payment.created` |
| `paypal_dispute` | [`paypal_dispute.json`](https://revcent.com/documentation/files/function/event/account_event/paypal_dispute.json) | `paypal_dispute.created` |
| `paypal_transaction` | [`paypal_transaction.json`](https://revcent.com/documentation/files/function/event/account_event/paypal_transaction.json) | `paypal_transaction.created` |
| `pending_refund` | [`pending_refund.json`](https://revcent.com/documentation/files/function/event/account_event/pending_refund.json) | `pending_refund.created`, `pending_refund.created.product_sale`, `pending_refund.created.product_sale.full`, `pending_refund.created.product_sale.partial`, `pending_refund.created.shipping`, `pending_refund.created.shipping.full`, `pending_refund.created.shipping.full.has_fulfillment`, `pending_refund.created.shipping.full.no_fulfillment`, `pending_refund.created.shipping.has_fulfillment`, `pending_refund.created.shipping.no_fulfillment`, `pending_refund.created.shipping.partial`, `pending_refund.created.shipping.partial.has_fulfillment`, `pending_refund.created.shipping.partial.no_fulfillment`, `pending_refund.created.subscription_renewal`, `pending_refund.created.subscription_renewal.full`, `pending_refund.created.subscription_renewal.partial`, `pending_refund.created.tax`, `pending_refund.created.tax.full`, `pending_refund.created.tax.partial` |
| `product` | [`product.json`](https://revcent.com/documentation/files/function/event/account_event/product.json) | `product.created`, `product.deleted`, `product.updated` |
| `product_sale` | [`product_sale.json`](https://revcent.com/documentation/files/function/event/account_event/product_sale.json) | `product_sale.created` |
| `sale` | [`sale.json`](https://revcent.com/documentation/files/function/event/account_event/sale.json) | `sale.created`, `sale.created.failed`, `sale.created.failed.declined`, `sale.created.failed.error`, `sale.created.failed.no_gateway`, `sale.created.failed.fraud_detected`, `sale.created.failed.merchant_error`, `sale.created.failed.merchant_hold`, `sale.created.success`, `sale.created.success.has_salvage`, `sale.created.success.is_upsell`, `sale.created.success.paid`, `sale.created.success.paid.has_salvage`, `sale.created.success.paid.is_upsell`, `sale.created.success.pending`, `sale.created.success.pending.is_upsell`, `sale.updated.fraud_alert.added`, `sale.updated.fraud_alert.removed` |
| `salvage_transaction` | [`salvage_transaction.json`](https://revcent.com/documentation/files/function/event/account_event/salvage_transaction.json) | `salvage_transaction.created`, `salvage_transaction.updated.processed`, `salvage_transaction.updated.processed.failed`, `salvage_transaction.updated.processed.success` |
| `sentinel` | [`sentinel.json`](https://revcent.com/documentation/files/function/event/account_event/sentinel.json) | `sentinel.alert`, `sentinel.alert.fraud_detected`, `sentinel.alert.firewall_block` |
| `shipping` | [`shipping.json`](https://revcent.com/documentation/files/function/event/account_event/shipping.json) | `shipping.created`, `shipping.created.has_fulfillment`, `shipping.created.no_fulfillment`, `shipping.updated.delivered`, `shipping.updated.ship_to`, `shipping.updated.shipped` |
| `subscription` | [`subscription.json`](https://revcent.com/documentation/files/function/event/account_event/subscription.json) | `subscription.created`, `subscription.updated.renewed`, `subscription.updated.renewed.failed`, `subscription.updated.renewed.success`, `subscription.updated.status`, `subscription.updated.status.active`, `subscription.updated.status.cancelled`, `subscription.updated.status.occurrence_limit`, `subscription.updated.status.overdue`, `subscription.updated.status.suspended` |
| `subscription_renewal` | [`subscription_renewal.json`](https://revcent.com/documentation/files/function/event/account_event/subscription_renewal.json) | `subscription_renewal.updated.failed`, `subscription_renewal.updated.success` |
| `tax` | [`tax.json`](https://revcent.com/documentation/files/function/event/account_event/tax.json) | `tax.created` |
| `transaction` | [`transaction.json`](https://revcent.com/documentation/files/function/event/account_event/transaction.json) | `transaction.created` |
| `trial` | [`trial.json`](https://revcent.com/documentation/files/function/event/account_event/trial.json) | `trial.created`, `trial.updated.cancelled`, `trial.updated.expired`, `trial.updated.expired.failed`, `trial.updated.expired.success`, `trial.updated.extended`, `trial.updated.shortened` |



Best practices:

- Use the most specific notation available.
- For example, prefer `sale.created.success.paid` if the Function should only run for paid successful sales.
- Use broader notations like `sale.created` only if the Function should handle all sale outcomes.
- Confirm the event data shape for each notation before writing code.

---

## `account_event_filters`

**Type:** `object`  
**Required:** No  
**Applies when:** `event_source` is `account_event`

Filters account events to determine whether the Function should run.

Schema:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "account_event_filters": {
    "campaign_filter": ["XXXXXXXXXXXXXXXXXXXX"]
  }
}
```

### `account_event_filters.campaign_filter`

**Type:** `array<string>`

A list of 20-character Campaign IDs.

Behavior:

- The Function only triggers when the account event is related to one of the listed campaigns.
- The related event must contain campaign context for the filter to apply.
- Omit `account_event_filters` if no filter should be changed.

---

## `timing_options`

**Type:** `object`  
**Required:** No  
**Applies when:** `event_source` is `account_event`

Determines when the Function runs after being triggered by an account event.

If not provided, the Function runs immediately after being triggered.

Schema:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "timing_options": {
    "timing": "delay",
    "time_unit": "hours",
    "time_value": 2
  }
}
```

### `timing_options.timing`

**Type:** `string` enum

Allowed values:

```text
immediate
delay
```

Behavior:

- `immediate`: run immediately when the account event occurs.
- `delay`: run after the configured delay.

### `timing_options.time_unit`

**Type:** `string` enum

Allowed values:

```text
minutes
hours
```

Required if `timing` is `delay`.

### `timing_options.time_value`

**Type:** `integer`

The numeric delay amount.

Required if `timing` is `delay`.

Example:

```json
{
  "timing": "delay",
  "time_unit": "hours",
  "time_value": 2
}
```

This runs the Function 2 hours after the account event occurs.

---

## `cron_expression`

**Type:** `string`  
**Required:** No  
**Applies when:** `event_source` is `schedule`

The cron expression that determines when the Function runs.

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "event_source": "schedule",
  "cron_expression": "0 9 * * *",
  "cron_timezone": "America/New_York"
}
```

Requirements:

- Must be a valid 5-part cron expression.
- Applies only to scheduled Functions.
- Pair with `cron_timezone` when schedule timing should be interpreted in a specific timezone.

Example 5-part cron:

```text
0 9 * * *
```

Meaning: every day at 9:00 AM in the configured timezone.

---

## `cron_timezone`

**Type:** `string`  
**Required:** No  
**Applies when:** `event_source` is `schedule`

The timezone for the cron expression.

```json
"cron_timezone": "America/New_York"
```

Behavior:

- Must be a valid IANA timezone string.
- If omitted, UTC is used.

Examples:

```text
UTC
America/New_York
America/Los_Angeles
Europe/London
```

---

# Dependencies

## `dependencies`

**Type:** `array<object>`  
**Required:** No

A list of dependencies required by the Function.

Important behavior:

- Only specific dependencies are supported.
- Dependencies are accessed within the function code using:

```javascript
global["<dependency_name>"]
```

- Do not use `require()`, `import`, or any other module loading mechanism.
- Dependencies are already available through the global object.
- When modifying dependencies, it may take up to 2 minutes for dependencies to update in the provisioned environment.
- If you provide the `dependencies` array, any existing dependencies are replaced with the submitted list.
- To preserve previous dependencies, call `GetFunction` first, copy the existing dependencies, and include them in the edit request.

Example:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "dependencies": [
    {
      "name": "axios",
      "version": "1.6.0"
    },
    {
      "name": "lodash",
      "version": "4.17.21"
    }
  ]
}
```

Function code usage:

```javascript
const axios = global["axios"];
const lodash = global["lodash"];
```

### Supported Dependency Names

```text
@mailchimp/mailchimp_marketing
@mailchimp/mailchimp_transactional
@sendgrid/mail
@slack/web-api
activecampaign
ajv
ascii-table
axios
crypto-js
facebook-nodejs-business-sdk
google-ads-api
google-libphonenumber
handlebars
html-to-text
input
json2csv
jsonwebtoken
klaviyo-sdk
lodash
mathjs
moment
moment-timezone
mongodb
mysql
nodemailer
openai
pg
qs
redis
request
shippo
superagent
twilio
uuid
validator
xml2js
```

### `dependencies[].name`

**Type:** `string` enum

The supported dependency name.

### `dependencies[].version`

**Type:** `string`

The dependency version.

Important:

- Ensure the version exists and is valid.
- Invalid versions can cause errors when triggering the Function.

---

# Environment Variables

## `environment_variables`

**Type:** `array<object>`  
**Required:** No

A list of environment variables available to the Function when triggered.

Environment variables are accessed with:

```javascript
process.env["<env_variable_name>"]
```

Example:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "environment_variables": [
    {
      "name": "SLACK_BOT_TOKEN",
      "value": "xoxb-example"
    },
    {
      "name": "SLACK_CHANNEL_ID",
      "value": "C1234567890"
    }
  ]
}
```

Function code usage:

```javascript
const token = process.env["SLACK_BOT_TOKEN"];
const channel = process.env["SLACK_CHANNEL_ID"];
```

Important behavior:

- Encrypted environment variables are decrypted and provided when the Function is triggered.
- When retrieving Function details via the API, encrypted environment variable values are hidden and not provided.
- This allows sensitive values such as API keys to be used by the Function without exposing them in retrieval responses.
- When editing a Function, providing `environment_variables` upserts variables.
- Existing variables are left intact.
- New variables are added/encrypted.
- Matching variable names have their values replaced.
- Providing `environment_variables` does not overwrite all existing environment variables.

### `environment_variables[].name`

**Type:** `string`

The environment variable name.

### `environment_variables[].value`

**Type:** `string`

The environment variable value.

Best practices:

- Use clear uppercase names, such as `SLACK_BOT_TOKEN`.
- Do not hardcode secrets in `function_code`.
- Only include `environment_variables` when adding or updating variables.

---


---

# Key Values in Functions

RevCent Key Values are account-wide values that Functions can read and, for string Key Values, update.

Key Values are useful for Function state management, shared configuration, feature flags, cursors, checkpoints, and reusable account-wide values.

Important:

```text
There is no EditFunction field named key_values.
Key Values are accessed from inside function_code.
```

No extra dependency is required to use Key Values. They are accessed through the RevCent Function object:

```javascript
global["revcent"]
```

---

## Reading a Key Value

Use:

```javascript
global["revcent"].GetKeyValue(my_key, callback)
```

Example:

```javascript
global["revcent"].GetKeyValue("support_email", function(error, value) {
  if (error) {
    callback(error);
    return;
  }

  callback(null, {
    support_email: value
  });
});
```

Use cases:

- Read shared configuration.
- Read a feature flag.
- Read a threshold.
- Read a Function state cursor.
- Read a pointer value such as an account-wide payment profile pointer.
- Read shared values used by multiple Functions.

---

## Updating a Key Value

Use:

```javascript
global["revcent"].UpdateKeyValue(my_key, value, callback)
```

Example:

```javascript
global["revcent"].UpdateKeyValue("last_processed_sale", "XXXXXXXXXXXXXXXXXXXX", callback);
```

Important limitation:

```text
Functions can update only Key Values where key_type = string.
Pointer Key Values cannot be updated from inside a Function.
```

MCP/AI should not write Function code that attempts to update a pointer Key Value.

---

## State Management With JSON Strings

For structured Function state, store JSON as a string.

Example Key Value:

```text
key: daily_report_cursor
key_type: string
value: {"last_run_unix":0,"last_processed_sale_id":null}
```

Function code:

```javascript
global["revcent"].GetKeyValue("daily_report_cursor", function(error, value) {
  if (error) {
    callback(error);
    return;
  }

  let state = {};
  try {
    state = JSON.parse(value || "{}");
  } catch (parseError) {
    callback(parseError);
    return;
  }

  // Use state.last_run_unix or state.last_processed_sale_id here.

  const nextState = JSON.stringify({
    last_run_unix: Math.floor(Date.now() / 1000),
    last_processed_sale_id: "XXXXXXXXXXXXXXXXXXXX"
  });

  global["revcent"].UpdateKeyValue("daily_report_cursor", nextState, callback);
});
```

Always validate and parse JSON carefully. If JSON parsing fails, call `callback(parseError)` and return.

---

## Common Function Key Value Use Cases

| Use Case | Example Key | Example Value |
|---|---|---|
| Last processed item cursor | `last_processed_sale` | `XXXXXXXXXXXXXXXXXXXX` |
| Scheduled report checkpoint | `daily_report_cursor` | `{"last_run_unix":1770000000}` |
| External sync cursor | `shipping_sync_cursor` | `{"cursor":"abc123","last_sync_unix":1770000000}` |
| Feature flag | `fraud_alerts_enabled` | `true` |
| Dynamic threshold | `vip_ltv_threshold` | `500` |
| Shared support config | `support_email` | `support@example.com` |
| Payment profile alias | `active_payment_profile` | pointer to payment profile |

---

## Key Values vs Environment Variables

Key Values and environment variables should not be confused.

| Feature | Best For |
|---|---|
| Key Values | Account-wide shared settings, non-secret configuration, state, cursors, feature flags, thresholds. |
| Environment Variables | Secrets, API keys, tokens, private credentials, passwords, per-Function sensitive configuration. |

Do this:

```javascript
const token = process.env["SLACK_BOT_TOKEN"];
```

for secrets.

Do this:

```javascript
global["revcent"].GetKeyValue("fraud_alerts_enabled", function(error, value) {
  if (error) {
    callback(error);
    return;
  }

  if (value !== "true") {
    callback(null, { skipped: true });
    return;
  }

  callback(null, { alerts_enabled: true });
});
```

for non-secret shared configuration.

---

## Key Values vs Metadata

Key Values are not metadata.

| Feature | Scope |
|---|---|
| Key Value | Account-wide and accessed by key. |
| Metadata | Attached to a specific RevCent item such as a customer, sale, transaction, or subscription. |

Use metadata when storing data on a specific item.

Use Key Values when storing a shared account-level value or Function state.

---

## Pointer Key Values in Functions

Pointer Key Values can point to supported RevCent entities, currently including payment profiles.

A Function may read a pointer Key Value when it needs an account-wide alias.

Example concept:

```text
active_payment_profile → Primary Credit Card Payment Profile
```

Important:

- Pointer Key Values should be created or edited with Key Value operations, not from inside the Function.
- Functions cannot update pointer Key Values through `UpdateKeyValue`.
- If a pointer controls payment behavior or API-call routing, changing it can be high-impact.

---

## Function State Management Best Practices

When using Key Values as Function state:

1. Use `key_type = string`.
2. Store structured state as JSON string.
3. Keep values under the Key Value size limit.
4. Use clear keys such as `daily_report_cursor` or `last_processed_sale`.
5. Retrieve the current state before updating it.
6. Preserve existing JSON properties unless intentionally resetting state.
7. Do not store secrets in Key Values.
8. Do not update pointer Key Values from Functions.
9. Avoid multiple Functions updating the same state key unless intentionally designed.
10. Do not assume Key Value updates are atomic unless RevCent explicitly documents atomic behavior.
11. Always call `callback` after `GetKeyValue` / `UpdateKeyValue` logic completes.
12. Return after calling `callback` when there is code below it.

---

## Example: Feature Flag

```javascript
global["revcent"].GetKeyValue("fraud_alerts_enabled", function(error, value) {
  if (error) {
    callback(error);
    return;
  }

  if (value !== "true") {
    callback(null, {
      skipped: true,
      reason: "Fraud alerts are disabled."
    });
    return;
  }

  // Continue with fraud alert logic here.

  callback(null, {
    skipped: false,
    alerts_enabled: true
  });
});
```

---

## Example: Dynamic Threshold

```javascript
global["revcent"].GetKeyValue("vip_ltv_threshold", function(error, value) {
  if (error) {
    callback(error);
    return;
  }

  const threshold = Number(value || 0);
  const customer = event?.data?.item_details?.customer || event?.data?.item_details;
  const ltv = Number(customer?.lifetime_value || 0);

  callback(null, {
    is_vip: ltv >= threshold,
    threshold: threshold,
    lifetime_value: ltv
  });
});
```

---

## Example: Scheduled Function Cursor

```javascript
global["revcent"].GetKeyValue("daily_report_cursor", function(error, value) {
  if (error) {
    callback(error);
    return;
  }

  let state = {};
  try {
    state = JSON.parse(value || "{}");
  } catch (parseError) {
    callback(parseError);
    return;
  }

  // Run report logic using state.last_run_unix.

  const nextState = JSON.stringify({
    last_run_unix: Math.floor(Date.now() / 1000)
  });

  global["revcent"].UpdateKeyValue("daily_report_cursor", nextState, callback);
});
```


# Function URL / Webhook Security

## `ip_restricted`

**Type:** `boolean`  
**Required:** No  
**Applies when:** `event_source` is `function_url` or webhook-style usage

Whether the Function is IP restricted.

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "ip_restricted": true
}
```

Behavior:

- If `true`, only allowed IP addresses can trigger the Function.
- Only applies to Functions with `event_source` set to `function_url` or webhook-style external triggering.
- Use this for partner integrations or public endpoints whenever possible.

---

## `ip_whitelist`

**Type:** `array<string>`  
**Required:** No  
**Applies when:** `ip_restricted` is `true`

The list of allowed IPv4 addresses.

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "ip_restricted": true,
  "ip_whitelist": ["203.0.113.10", "198.51.100.25"]
}
```

Requirements:

- Each entry should be a valid IPv4 address.
- IP ranges are not supported.
- CIDR notation is not supported by the schema description.
- Only exact IPv4 addresses should be provided.

---

# API / AI Custom Arguments

## `custom_arguments`

**Type:** `array<object>`  
**Required:** No  
**Applies only when:** `event_source` is `api_direct` **and the Function is not being used as a filter Function**

Defines custom arguments that should be provided when triggering the Function using `TriggerFunction`.

Important behavior:

- Only include `custom_arguments` for normal API/MCP or AI tool-triggered `api_direct` Functions.
- Do not include `custom_arguments` when the `api_direct` Function is being used as a filter Function for AI Assistants or AI Voice Agents.
- Filter Functions receive their input from the item context event body, based on `item_type` and `item_id`.
- Filter Function event bodies use the pattern `https://revcent.com/documentation/files/function/event/filter/<item_type>.json`.
- Custom arguments are intended to be used by AI to infer values when directly triggering the Function.
- If `custom_arguments` is provided, any existing custom arguments are replaced with the submitted list.
- To preserve previous custom arguments, call `GetFunction` first and include existing arguments in the edit request.
- Custom argument names should contain letters and underscores only, with no spaces.

Example:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "event_source": "api_direct",
  "custom_arguments": [
    {
      "name": "sale_id",
      "description": "The 20-character sale ID to process."
    },
    {
      "name": "summary_reason",
      "description": "A short explanation of why this function is being triggered."
    }
  ]
}
```

### `custom_arguments[].name`

**Type:** `string`

The custom argument name.

Rules:

- Letters and underscores only.
- No spaces.

### `custom_arguments[].description`

**Type:** `string`

The description used to determine what value should be provided when the Function is triggered.

Good description:

```text
The 20-character sale ID for the sale that should be summarized.
```

Poor description:

```text
sale
```

Function code should read the runtime argument format according to the trigger payload supplied by `TriggerFunction`.

---

# Event Source Setup Examples

## Account Event Function

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "enabled": true,
  "event_source": "account_event",
  "account_event_notations": ["sale.created.success.paid"],
  "account_event_filters": {
    "campaign_filter": ["YYYYYYYYYYYYYYYYYYYY"]
  },
  "timing_options": {
    "timing": "immediate"
  }
}
```

Use when the Function should run automatically when a matching RevCent account event occurs.

---

## Delayed Account Event Function

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "event_source": "account_event",
  "account_event_notations": ["sale.created.success"],
  "timing_options": {
    "timing": "delay",
    "time_unit": "hours",
    "time_value": 2
  }
}
```

Use when the Function should run after a delay.

---

## Scheduled Function

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "enabled": true,
  "event_source": "schedule",
  "cron_expression": "0 9 * * *",
  "cron_timezone": "America/New_York"
}
```

Use when the Function should run on a fixed schedule.

---

## API / AI Direct Function

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "enabled": true,
  "event_source": "api_direct",
  "custom_arguments": [
    {
      "name": "customer_email",
      "description": "The customer's email address."
    },
    {
      "name": "message_body",
      "description": "The message body to process."
    }
  ]
}
```

Use when the Function should be triggered by API/MCP or AI.

---

## API Direct Filter Function for AI Assistants or AI Voice Agents

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "enabled": true,
  "event_source": "api_direct",
  "function_code": "let item = event.data.item_details; if (item && item.enabled !== false) { callback(null, 'pass'); } else { callback(null, 'fail'); }"
}
```

Do not include `custom_arguments` for this filter Function configuration. The filter Function receives its input from the item context.

Use the filter event body for the item type being evaluated:

```text
https://revcent.com/documentation/files/function/event/filter/<item_type>.json
```

For example, a sale filter Function should reference:

```text
https://revcent.com/documentation/files/function/event/filter/sale.json
```

---

## Email Template Custom Data Function

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "enabled": true,
  "event_source": "email_template",
  "function_code": "let item = event.data.item_details; callback(null, { customer_email: item.customer.email });"
}
```

Use with an Email Template custom data configuration:

```json
{
  "custom_data": {
    "enabled": true,
    "source_type": "custom_function",
    "source_value": "XXXXXXXXXXXXXXXXXXXX"
  }
}
```

Where `source_value` is the Function ID.

---

## Function URL with IP Restriction

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "enabled": true,
  "event_source": "function_url",
  "ip_restricted": true,
  "ip_whitelist": ["203.0.113.10"]
}
```

Use for external HTTP-triggered integrations.

---

## Function with Dependencies and Environment Variables

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "dependencies": [
    {
      "name": "axios",
      "version": "1.6.0"
    }
  ],
  "environment_variables": [
    {
      "name": "PARTNER_API_KEY",
      "value": "example-secret"
    }
  ],
  "function_code": "const axios = global['axios']; const apiKey = process.env['PARTNER_API_KEY']; callback(null, { configured: true });"
}
```

---

# Function Code Patterns

## Function Code Is the Handler Body Only

Do not include an outer handler declaration. RevCent already provides `event`, `context`, and `callback`.

Correct:

```javascript
callback(null, {
  success: true
});
```

Incorrect:

```javascript
exports.handler = async (event, context, callback) => {
  callback(null, {
    success: true
  });
};
```

## Minimal Success

```javascript
callback(null, {
  success: true
});
```

## Minimal Error

```javascript
callback(new Error("Something went wrong."));
```

## Safe Try/Catch

```javascript
try {
  callback(null, {
    success: true
  });
} catch (error) {
  callback(error);
}
```

## Using a Dependency

```javascript
const axios = global["axios"];

try {
  const response = await axios.post("https://example.com/webhook", {
    hello: "world"
  });

  callback(null, {
    status: response.status
  });
} catch (error) {
  callback(error);
}
```

## Using Environment Variables

```javascript
const apiKey = process.env["PARTNER_API_KEY"];

if (!apiKey) {
  callback(new Error("Missing PARTNER_API_KEY."));
} else {
  callback(null, {
    has_api_key: true
  });
}
```

## Returning Email Template Custom Data

```javascript
try {
  let item = event.data.item_details;

  callback(null, {
    first_name_uppercase: item.customer.first_name.toUpperCase(),
    support_email: "support@example.com"
  });
} catch (error) {
  callback(error);
}
```

Email Template usage:

```handlebars
<p>Hello {{custom_data.first_name_uppercase}}</p>
<p>Need help? Email {{custom_data.support_email}}</p>
```

---

---

# Third-Party Integrations with Functions

RevCent Functions can be used to integrate with almost any third-party system because Function code can make outbound internet requests, use supported third-party dependencies, and securely access encrypted environment variables.

Use Functions when RevCent needs to:

- Send event data to a third-party system.
- Receive data from a third-party system.
- Transform RevCent data into an external API payload.
- Enrich RevCent events with external API data.
- Route payments based on external decisioning.
- Send Slack, SendGrid, Twilio, Mailchimp, CRM, fulfillment, analytics, or webhook requests.
- Build custom business logic that RevCent does not provide natively.

---

## Outbound Internet Access

Functions can make outbound internet requests to third-party APIs.

Typical use cases:

| Use Case | Example |
|---|---|
| Webhook forwarding | Send sale data to a partner endpoint. |
| CRM sync | Create or update a contact in an external CRM. |
| Slack notifications | Post account events to a Slack channel. |
| Email/SMS integrations | Send messages through SendGrid, Mailchimp, Twilio, or another provider. |
| Fulfillment integrations | Send shipping or product data to a warehouse or fulfillment provider. |
| Fraud/risk scoring | Call an external fraud service and return a pass/fail or routing decision. |
| Payment routing | Query an external decision engine before choosing a payment gateway. |
| AI integrations | Call OpenAI or another AI provider to generate summaries or structured output. |

Example using `axios`:

```javascript
const axios = global["axios"];

try {
  const response = await axios.post(
    "https://api.example.com/events",
    {
      event_type: event.data.item_type,
      item_id: event.data.item_id,
      item_details: event.data.item_details
    },
    {
      headers: {
        Authorization: `Bearer ${process.env["PARTNER_API_KEY"]}`,
        "Content-Type": "application/json"
      },
      timeout: 5000
    }
  );

  callback(null, {
    success: true,
    status: response.status
  });
} catch (error) {
  callback(error);
}
```

Important:

- Use timeouts for external requests.
- Handle API errors explicitly.
- Avoid long-running calls, especially inside `payment_profile` Functions.
- Do not assume a third-party API is always available.
- Build retry-safe and idempotent logic where possible.

---

## Supported Dependencies

Functions support a curated set of dependencies. Add dependencies through the `dependencies` array in `EditFunction`.

Important behavior:

- Dependencies are not imported with `require()` or `import`.
- Dependencies are accessed through the global object.
- Use this pattern:

```javascript
const axios = global["axios"];
const _ = global["lodash"];
const moment = global["moment"];
```

Do not use this:

```javascript
const axios = require("axios");
```

Example `EditFunction` dependency configuration:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "dependencies": [
    {
      "name": "axios",
      "version": "1.6.0"
    },
    {
      "name": "lodash",
      "version": "4.17.21"
    }
  ]
}
```

### Dependency Update Behavior

When the `dependencies` array is provided:

- The submitted list replaces the existing dependency list.
- To preserve current dependencies, call `GetFunction` first and include existing dependencies in the edit request.
- Dependency updates may take up to 2 minutes to apply in the provisioned Function environment.
- Invalid dependency names or versions can cause execution errors.

### Common Integration Dependencies

| Dependency | Common Use |
|---|---|
| `axios` | HTTP requests to third-party APIs. |
| `request` | Legacy HTTP requests. |
| `superagent` | HTTP requests. |
| `@slack/web-api` | Slack API integration. |
| `@sendgrid/mail` | SendGrid email sending. |
| `twilio` | Twilio SMS, voice, and communication APIs. |
| `nodemailer` | SMTP email sending. |
| `@mailchimp/mailchimp_marketing` | Mailchimp Marketing API. |
| `@mailchimp/mailchimp_transactional` | Mailchimp Transactional / Mandrill API. |
| `openai` | OpenAI API integration. |
| `klaviyo-sdk` | Klaviyo integration. |
| `activecampaign` | ActiveCampaign integration. |
| `shippo` | Shipping / fulfillment integration. |
| `facebook-nodejs-business-sdk` | Meta / Facebook Business API. |
| `google-ads-api` | Google Ads API integration. |
| `mongodb` | MongoDB integration. |
| `mysql` | MySQL integration. |
| `pg` | PostgreSQL integration. |
| `redis` | Redis integration. |
| `jsonwebtoken` | JWT creation or verification. |
| `crypto-js` | Hashing, HMAC signatures, encryption helpers. |
| `validator` | Input validation. |
| `ajv` | JSON schema validation. |
| `handlebars` | Template rendering. |
| `html-to-text` | Convert HTML to text. |
| `xml2js` | Parse XML responses. |
| `json2csv` | Convert JSON to CSV. |
| `moment` / `moment-timezone` | Date and timezone formatting. |
| `lodash` | Data manipulation helpers. |

---

## Encrypted Environment Variables

Use `environment_variables` for secrets, tokens, API keys, webhook signing secrets, and other private values.

Environment variables are available in Function code using:

```javascript
process.env["VARIABLE_NAME"]
```

Example configuration:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "environment_variables": [
    {
      "name": "PARTNER_API_KEY",
      "value": "example-secret"
    },
    {
      "name": "SLACK_BOT_TOKEN",
      "value": "xoxb-example"
    }
  ]
}
```

Example usage:

```javascript
const apiKey = process.env["PARTNER_API_KEY"];

if (!apiKey) {
  callback(new Error("Missing PARTNER_API_KEY."));
} else {
  callback(null, {
    configured: true
  });
}
```

Important behavior:

- Environment variables are encrypted.
- Encrypted values are decrypted when the Function runs.
- When retrieving Function details via API, encrypted values are hidden and not returned.
- Providing `environment_variables` in `EditFunction` upserts variables.
- Existing variables are left intact when omitted.
- Matching variable names have their values replaced.
- New variable names are added and encrypted.
- Omitted variables are not removed by an upsert.

Best practices:

- Never hardcode secrets in `function_code`.
- Use uppercase names such as `SLACK_BOT_TOKEN`, `OPENAI_API_KEY`, or `PARTNER_WEBHOOK_SECRET`.
- Keep environment variables scoped to the Function that needs them.
- Rotate secrets periodically.
- Avoid returning secret values in `callback` responses.
- Avoid logging secret values.

---

## Integration Pattern: Send a Webhook to a Partner

Use this pattern for event forwarding.

```javascript
const axios = global["axios"];

try {
  const partnerUrl = process.env["PARTNER_WEBHOOK_URL"];
  const apiKey = process.env["PARTNER_API_KEY"];

  if (!partnerUrl || !apiKey) {
    throw new Error("Missing partner webhook configuration.");
  }

  const payload = {
    item_type: event.data.item_type,
    item_id: event.data.item_id,
    item_details: event.data.item_details
  };

  const response = await axios.post(partnerUrl, payload, {
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json"
    },
    timeout: 5000
  });

  callback(null, {
    success: true,
    partner_status: response.status
  });
} catch (error) {
  callback(error);
}
```

Recommended dependencies:

```json
[
  {
    "name": "axios",
    "version": "1.6.0"
  }
]
```

Recommended environment variables:

```json
[
  {
    "name": "PARTNER_WEBHOOK_URL",
    "value": "https://partner.example.com/webhook"
  },
  {
    "name": "PARTNER_API_KEY",
    "value": "secret"
  }
]
```

---

## Integration Pattern: Post to Slack

Use this pattern for internal notifications.

```javascript
const { WebClient } = global["@slack/web-api"];

try {
  const token = process.env["SLACK_BOT_TOKEN"];
  const channel = process.env["SLACK_CHANNEL_ID"];

  if (!token || !channel) {
    throw new Error("Missing Slack configuration.");
  }

  const slack = new WebClient(token);

  const itemType = event.data.item_type;
  const itemId = event.data.item_id;

  await slack.chat.postMessage({
    channel,
    text: `RevCent event received: ${itemType} ${itemId}`
  });

  callback(null, {
    success: true
  });
} catch (error) {
  callback(error);
}
```

Recommended dependencies:

```json
[
  {
    "name": "@slack/web-api",
    "version": "6.12.0"
  }
]
```

Recommended environment variables:

```json
[
  {
    "name": "SLACK_BOT_TOKEN",
    "value": "xoxb-secret"
  },
  {
    "name": "SLACK_CHANNEL_ID",
    "value": "C1234567890"
  }
]
```

---

## Integration Pattern: Generate Data for an Email Template

Use this pattern when an Email Template uses a Function as a `custom_data` source.

```javascript
try {
  const item = event.data.item_details;

  callback(null, {
    customer_email_domain: item.customer.email.split("@")[1],
    support_email: process.env["SUPPORT_EMAIL"],
    personalized_footer: "Thank you for being a customer."
  });
} catch (error) {
  callback(error);
}
```

Email Template usage:

```handlebars
<p>Support: {{custom_data.support_email}}</p>
<p>{{custom_data.personalized_footer}}</p>
```

Recommended environment variables:

```json
[
  {
    "name": "SUPPORT_EMAIL",
    "value": "support@example.com"
  }
]
```

---

## Integration Pattern: Payment Profile External Decisioning

Use this pattern when a `payment_profile` Function calls an external decisioning API and returns a flow response.

```javascript
const axios = global["axios"];

try {
  const item = event.data.item_details;
  const decisionUrl = process.env["DECISION_API_URL"];
  const apiKey = process.env["DECISION_API_KEY"];

  if (!decisionUrl || !apiKey) {
    throw new Error("Missing decision API configuration.");
  }

  const decision = await axios.post(
    decisionUrl,
    {
      payment_amount: item.payment_amount,
      customer: item.customer,
      customer_card: item.customer_card,
      gateway_history: item.gateway_history
    },
    {
      headers: {
        Authorization: `Bearer ${apiKey}`,
        "Content-Type": "application/json"
      },
      timeout: 3000
    }
  );

  if (decision.data.abort === true) {
    callback(null, {
      next_output: "2",
      custom_error: decision.data.message || "Payment could not be processed."
    });
    return;
  }

  if (decision.data.gateway_id) {
    callback(null, {
      set_gateway_id: decision.data.gateway_id,
      next_node_id: decision.data.next_node_id
    });
    return;
  }

  callback(null, {
    next_output: "1"
  });
} catch (error) {
  callback(error);
}
```

Important:

- Keep timeout low for payment-profile integrations.
- Always configure a red-output fallback path in the payment flow.
- Return only response properties needed by the flow.
- Do not call slow external systems from payment flows unless necessary.

---

## Integration Security Checklist

Before using a Function for third-party integration:

1. Store API keys and secrets in encrypted `environment_variables`.
2. Do not hardcode secrets in `function_code`.
3. Add only the dependencies required.
4. Access dependencies with `global["dependency_name"]`.
5. Add HTTP request timeouts.
6. Validate event payload fields before sending them externally.
7. Avoid sending unnecessary customer or payment data.
8. Avoid logging sensitive data.
9. Use idempotency keys when sending events that might be retried.
10. Handle third-party downtime gracefully.
11. For payment-profile Functions, keep execution within the 8-second response window.
12. For URL/webhook Functions, validate inbound payloads and restrict IPs where possible.
13. Return safe, minimal responses.
14. Test with realistic payloads before enabling production usage.

# Output Schema

A successful `EditFunction` response returns:

```json
{
  "api_call_id": "XXXXXXXXXXXXXXXXXXXX",
  "api_call_unix": 1740000000,
  "code": 1,
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "result": "..."
}
```

Fields:

| Field | Type | Description |
|---|---:|---|
| `api_call_id` | string | 20-character API call ID. |
| `api_call_unix` | integer | Unix timestamp when the API call was initiated. |
| `code` | integer | Response code. `1` indicates success. |
| `function_id` | string | 20-character ID of the edited Function. |
| `result` | string | Human-readable result message. |

---



---

# Newly Created Function Provisioning Delay

Newly created Functions require time to provision before they can be fully edited or updated.

Important behavior:

- After creating a new Function, wait at least **30 seconds** before attempting to edit it.
- If an `EditFunction` request returns a `"still provisioning"` error, wait at least **30 more seconds** and try the request again.
- Dependency updates may still require additional provisioning time after the Function becomes editable.
- Newly created or recently updated Functions may not immediately reflect dependency or environment changes across all provisioned environments.

Best practices:

1. Create the Function first.
2. Wait at least 30 seconds before the first edit attempt.
3. If a provisioning-related error occurs, wait another 30 seconds and retry.
4. Avoid rapid repeated edit requests immediately after Function creation.


# Replacement vs Upsert Behavior

| Field | Behavior when provided |
|---|---|
| `name` | Updates the name. |
| `description` | Updates the description. |
| `enabled` | Updates enabled status. |
| `function_code` | Replaces the Function code. |
| `event_source` | Updates the event source. |
| `account_event_notations` | Updates/replaces event notations. |
| `account_event_filters` | Updates provided filters. |
| `timing_options` | Updates timing options. |
| `cron_expression` | Updates scheduled cron expression. |
| `cron_timezone` | Updates scheduled timezone. |
| `dependencies` | Replaces the existing dependency list. |
| `environment_variables` | Upserts variables; does not remove omitted existing variables. |
| `ip_restricted` | Updates IP restriction setting. |
| `ip_whitelist` | Updates/replaces whitelist values. |
| `custom_arguments` | Replaces the existing custom argument list. |

---

# Implementation Checklist

Before calling `EditFunction`:

1. Confirm the `function_id` is correct.
2. Include only fields you intend to modify.
3. If editing `function_code`, submit only the Function body; do not include `exports.handler`, `module.exports`, or any custom `(event, context, callback)` wrapper.
22. If editing `function_code`, ensure every execution path calls `callback(error, response)`.
4. If changing `event_source`, remove or update fields that only apply to the old source.
5. For `account_event`, configure `account_event_notations` and use the first notation segment to find the event JSON body, for example `sale.created` → `https://revcent.com/documentation/files/function/event/account_event/sale.json`.
6. For `account_event`, add `account_event_filters` only when filtering is needed.
7. For `payment_profile`, use the Payment Profile event body JSON as the source of truth: `https://revcent.com/documentation/files/function/event/payment_profile.json`.
20. For delayed account events, provide valid `timing_options`.
8. For `schedule`, provide a valid 5-part `cron_expression`.
9. For `schedule`, provide a valid IANA `cron_timezone` when local time matters.
10. For dependencies, call `GetFunction` first if you need to preserve existing dependencies.
11. Do not use `require()` or `import`; access dependencies with `global["dependency_name"]`.
12. Allow up to 2 minutes for dependency changes to update in the provisioned environment.
13. Use environment variables for secrets instead of hardcoding them.
14. Remember environment variables are upserted, not fully replaced.
15. For `function_url`, use IP restriction where possible.
16. For normal `api_direct` triggering, define clear `custom_arguments` with letters and underscores only.
20. For `api_direct` filter Function usage, do not include `custom_arguments`; use the filter event body based on `item_type` and return only `pass` or `fail`.
17. Call `GetFunction` first if you need to preserve existing custom arguments.
18. Use the correct event-body JSON reference for the configured trigger type:
    - account_event → account_event/<item_type>.json
    - api_direct → https://revcent.com/documentation/files/function/event/api_direct.json; as AI Assistant / AI Voice Agent filter Function → https://revcent.com/documentation/files/function/event/filter/<item_type>.json
    - payment_profile → https://revcent.com/documentation/files/function/event/payment_profile.json
    - function_url → https://revcent.com/documentation/files/function/event/function_url.json
    - webhook → https://revcent.com/documentation/files/function/event/webhook.json
    - schedule → https://revcent.com/documentation/files/function/event/schedule.json
    - pre_agent → https://revcent.com/documentation/files/function/event/pre_agent.json (AI Voice Agent pre-agent Function for Handlebars instruction content)
19. Test the Function with realistic payloads before enabling production behavior.
20. Enable the Function only after code and configuration are validated.

---

# Quick Reference

Rename only:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "name": "Updated Function Name"
}
```

Disable Function:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "enabled": false
}
```

Configure API-direct Function:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "enabled": true,
  "event_source": "api_direct",
  "custom_arguments": [
    {
      "name": "sale_id",
      "description": "The 20-character sale ID."
    }
  ]
}
```

Configure account-event Function:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "enabled": true,
  "event_source": "account_event",
  "account_event_notations": ["sale.created.success.paid"]
}
```

Configure scheduled Function:

```json
{
  "function_id": "XXXXXXXXXXXXXXXXXXXX",
  "enabled": true,
  "event_source": "schedule",
  "cron_expression": "0 9 * * *",
  "cron_timezone": "America/New_York"
}
```


---
Document Parent Directory
* [Operations](https://revcent.com/documentation/markdown/mcp/operation/index.md) - AI/MCP details and overviews for operations available within the RevCent MCP.