# RevCent MCP Operation: `EditCustomerPortal`

This document explains the `EditCustomerPortal` operation in depth so MCP clients can correctly edit existing Customer Portals in RevCent.

This is an operation-specific MCP guide. It explains partial edit behavior, required fields, editable properties, nested objects, high-risk permission changes, DNS/SSL requirements, customer filters, customer emails, reCAPTCHA updates, and validation rules.

Sources:
- RevCent API/MCP schema for `EditCustomerPortal`
- RevCent API/MCP schema for `CreateCustomerPortal`
- RevCent Knowledge Base: [Customer Portal](https://kb.revcent.com/en/customer/customer-portal)
- RevCent Customer Portals overview guidance

---

## Operation Summary

`EditCustomerPortal` edits a previously created Customer Portal using the required `customer_portal_id`.

The operation is a partial-update operation.

The schema description is explicit:

```text
Only include the properties you wish to modify.
```

For example:

- If only the portal name should change, include only `customer_portal_id` and `name`.
- If only the portal should be disabled, include only `customer_portal_id` and `enabled`.
- If only customer permissions should change, include only `customer_portal_id` and `customer_permissions`.
- If customer emails should change, include only `customer_portal_id` and `customer_emails`, but provide the complete intended email objects.

Do not send fields unnecessarily.

---

# What Customer Portals Do

A Customer Portal is a customer-facing self-service portal connected to RevCent customer data.

Depending on configuration, customers may be able to:

- Confirm account registration
- Reset their password
- Modify contact information
- Add credit cards
- Remove credit cards
- Set a default credit card
- Modify shipping information
- Renew subscriptions
- Re-activate subscriptions
- Suspend subscriptions
- Cancel subscriptions
- Expire trials
- Cancel trials
- Pay failed renewals or failed trial expirations through the system permission `salvage_transaction_process`

Editing a portal can change what customers can access, what they can do, what brand/site experience they see, what emails they receive, and which customers are allowed to use the portal.

Because Customer Portals are customer-facing, edits should be handled carefully.

---

# Required Field

| Field | Type | Required | Description |
|---|---:|---:|---|
| `customer_portal_id` | string | Yes | The 20-character Customer Portal ID to edit. |

Minimal shape:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX"
}
```

A real edit should include at least one additional field to modify.

---

# Editable Fields

| Field | Type | Description |
|---|---:|---|
| `customer_portal_id` | string | Required 20-character Customer Portal ID. |
| `name` | string | Customer Portal name. Must be unique from other Customer Portal names. |
| `description` | string | Customer Portal description. |
| `enabled` | boolean | Whether the Customer Portal is enabled. |
| `tracking_domain` | string | 20-character tracking domain ID. Must be set up and have active SSL. |
| `recaptcha` | object | reCAPTCHA v2 “I’m Not A Robot” site and secret keys. |
| `display_name` | string | Customer-facing portal display name. If blank, portal name is used. |
| `footer_html` | string | Custom footer HTML for the customer portal. |
| `smtp_profile` | string | 20-character SMTP Profile ID. |
| `customer_emails` | object | Account confirmation and password reset email settings. |
| `customer_filters` | object | Determines which customers can access the portal. |
| `customer_permissions` | object | Determines what customers can do in the portal. |
| `create_non_existing_customer` | boolean | Whether non-existing customers can register. Recommended `false`. |
| `create_non_existing_customer_campaign` | string | Campaign ID used when non-existing customer registration is enabled. |

The schema has:

```json
"additionalProperties": false
```

MCP must not send unknown fields.

---

# Critical Edit Rule: Only Include Fields Being Modified

`EditCustomerPortal` should be treated as a partial-update operation.

Correct name-only edit:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "name": "Updated Customer Portal Name"
}
```

Correct enabled-only edit:

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

Correct display-name-only edit:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "display_name": "Manage Your Account"
}
```

Do not include unrelated fields.

Wrong:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "name": "Updated Customer Portal Name",
  "customer_permissions": {}
}
```

unless the intent is also to change customer permissions.

---

# Why Partial Edits Matter

Customer Portal settings are customer-facing.

Accidental edits can:

- Open access to all customers.
- Restrict access incorrectly.
- Allow customers to cancel subscriptions unintentionally.
- Prevent customers from updating payment methods.
- Break account confirmation emails.
- Break password reset emails.
- Remove `{{email_code}}` from email templates.
- Point the portal to the wrong tracking domain.
- Use a domain without active SSL.
- Change the portal branding for the wrong customers.
- Allow non-existing customers to register unexpectedly.
- Disable payment recovery through failed renewal or failed trial expiration payments.
- Affect iframe embedding on the merchant’s website.

Because of this, MCP should edit only what the user asked to change.

---

# Safe Edit Workflow

Recommended MCP workflow:

```text
1. Identify the customer_portal_id.
2. Determine exactly which fields need to change.
3. Retrieve or know the existing portal configuration if editing nested objects.
4. Preserve existing settings that should remain unchanged.
5. Validate high-risk fields before sending.
6. Submit only the intended edit fields.
7. Confirm the result.
```

For high-risk edits:

```text
Disable portal → edit settings → review/test → enable intentionally
```

High-risk edits include:

- Changing `tracking_domain`
- Changing `smtp_profile`
- Changing `recaptcha`
- Changing `customer_emails`
- Changing `customer_filters`
- Changing `customer_permissions`
- Enabling `subscription_cancel`
- Enabling `create_non_existing_customer`
- Enabling a portal before domain/email/testing is complete

---

# `name`

The `name` is the internal Customer Portal name.

Rules:

- Must be unique from other Customer Portal names.
- Should clearly identify the portal purpose.

Example:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "name": "Brand A Customer Portal"
}
```

Good names:

```text
Main Customer Portal
Subscription Customer Portal
Payment Recovery Portal
Brand A Customer Portal
WooCommerce Store Portal
```

---

# `description`

The `description` explains what the portal is for.

Example:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "description": "Customer self-service portal for Brand A customers to update payment methods and pay failed renewals or failed trial expirations."
}
```

A good description should explain:

- Who the portal is for
- What customers can do
- Whether it is tied to a brand, campaign, shop, website, or customer origin
- Whether it is used for payment recovery, subscriptions, trials, or account management

---

# `enabled`

`enabled` controls whether the Customer Portal is enabled.

Example disable:

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

Example enable:

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

Recommended behavior:

```text
Disable before risky edits.
Enable only after the portal configuration is reviewed and tested.
```

Do not enable a portal if:

- Tracking domain is not DNS ready.
- Tracking domain does not have active SSL.
- SMTP Profile is not valid.
- reCAPTCHA is not valid.
- Email templates are missing `{{email_code}}`.
- Permissions are not reviewed.
- Customer filters are not reviewed.

---

# `tracking_domain`

`tracking_domain` is the 20-character tracking domain ID used for the Customer Portal.

Example:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "tracking_domain": "YYYYYYYYYYYYYYYYYYYY"
}
```

The tracking domain must already be:

- Created
- DNS ready
- Properly configured with DNS records
- SSL initialized
- SSL active
- Appropriate for customer-facing portal use

The operation schema states:

```text
Make sure the tracking domain is set up and has an active SSL certificate before using it in the portal.
```

---

## High-Risk Tracking Domain Edit

Changing the tracking domain is high risk because it can affect:

- Customer access
- Portal URLs
- iframe embedding
- Brand/domain alignment
- reCAPTCHA domain compatibility
- SSL/security
- Customer trust

If changing `tracking_domain`, MCP should verify:

1. New tracking domain is DNS ready.
2. New tracking domain has active SSL.
3. reCAPTCHA keys are valid for the new domain.
4. Portal embedding, if any, uses the correct domain relationship.
5. Customer emails and links are still correct.
6. Portal should likely be disabled while changing/testing.

---

# `recaptcha`

`recaptcha` contains reCAPTCHA v2 “I’m Not A Robot” keys.

Shape:

```json
"recaptcha": {
  "site_key": "RECAPTCHA_SITE_KEY",
  "secret_key": "RECAPTCHA_SECRET_KEY"
}
```

Fields:

| Field | Type | Required Within Object | Description |
|---|---:|---:|---|
| `site_key` | string | Yes | reCAPTCHA v2 site key for the domain associated with the tracking domain. |
| `secret_key` | string | Yes | reCAPTCHA v2 secret key for the domain associated with the tracking domain. Encrypted then saved by RevCent. |

If editing reCAPTCHA, provide both:

```text
site_key
secret_key
```

because the nested object requires both fields.

Example:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "recaptcha": {
    "site_key": "NEW_RECAPTCHA_SITE_KEY",
    "secret_key": "NEW_RECAPTCHA_SECRET_KEY"
  }
}
```

Important:

- Do not invent keys.
- Use keys valid for the portal domain.
- If tracking domain changes, reCAPTCHA may need to change too.

---

# `display_name`

`display_name` is what customers see when using the portal.

If blank, the portal name is used.

Example:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "display_name": "Brand A Account Portal"
}
```

Use a customer-friendly display name, especially when the portal is brand-, website-, or store-specific.

---

# `footer_html`

`footer_html` allows custom footer HTML.

Example:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "footer_html": "<p>Need help? Contact support@brand-a.example.</p>"
}
```

Use cases:

- Support link
- Privacy policy link
- Terms link
- Brand footer
- Contact instructions
- Customer service guidance

MCP should keep footer HTML simple, safe, and customer-facing.

---

# `smtp_profile`

`smtp_profile` is the 20-character SMTP Profile ID used to send portal emails.

Example:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "smtp_profile": "YYYYYYYYYYYYYYYYYYYY"
}
```

Changing SMTP Profile is high impact because it can affect account confirmation and password reset emails.

If changing `smtp_profile`, MCP should verify:

- New SMTP Profile exists.
- Sender emails in `customer_emails` are compatible with the SMTP Profile.
- Confirmation email still works.
- Password reset email still works.

---

# `customer_emails`

`customer_emails` customizes portal emails for:

```text
customer_account_confirm_email
customer_account_password_reset
```

Shape:

```json
"customer_emails": {
  "customer_account_confirm_email": {},
  "customer_account_password_reset": {}
}
```

Important:

If editing `customer_emails`, MCP should provide the complete intended `customer_emails` object unless the API explicitly supports nested merging.

Do not send partial nested email objects unless only that exact replacement is intended.

The schema for each nested email requires:

```text
from
from_name
subject
html
to_cc
to_bcc
```

Both email templates must include:

```handlebars
{{email_code}}
```

---

## `customer_account_confirm_email`

The confirmation email is sent when customers confirm portal registration.

Required nested fields:

```text
from
from_name
subject
html
to_cc
to_bcc
```

Example:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "customer_emails": {
    "customer_account_confirm_email": {
      "from": "support@example.com",
      "from_name": "Example Store",
      "subject": "Confirm your customer portal account",
      "html": "<p>Your confirmation code is: <strong>{{email_code}}</strong></p>",
      "to_cc": [],
      "to_bcc": []
    },
    "customer_account_password_reset": {
      "from": "support@example.com",
      "from_name": "Example Store",
      "subject": "Reset your customer portal password",
      "html": "<p>Your password reset code is: <strong>{{email_code}}</strong></p>",
      "to_cc": [],
      "to_bcc": []
    }
  }
}
```

---

## `customer_account_password_reset`

The password reset email is sent when customers request a password reset.

Required nested fields:

```text
from
from_name
subject
html
to_cc
to_bcc
```

The `html` must include:

```handlebars
{{email_code}}
```

Without this shortcode, the customer may not be able to reset their password.

---

## Critical Email Shortcode Requirement

Both templates must include:

```handlebars
{{email_code}}
```

Required in:

```text
customer_account_confirm_email.html
customer_account_password_reset.html
```

MCP should validate this every time `customer_emails` is edited.

---

# `customer_filters`

`customer_filters` determines which customers can access the portal.

If no filters are set, all customers can access the portal.

Shape:

```json
"customer_filters": {
  "campaign": [],
  "third_party_shop": []
}
```

Available filters:

| Field | Type | Meaning |
|---|---:|---|
| `campaign` | array<string> | Customers associated with at least one listed campaign can access the portal. |
| `third_party_shop` | array<string> | Customers associated with at least one listed third-party shop can access the portal. |

Each ID must be 20 characters.

---

## High-Risk Customer Filter Edit

Changing `customer_filters` changes who can access the portal.

If filters are removed or omitted in a replacement, the portal may become accessible to all customers.

If filters are narrowed, customers who previously had access may lose access.

MCP should confirm whether the portal should be:

```text
Global portal for all customers
```

or:

```text
Filtered portal for specific brands, websites, campaigns, or shops
```

---

# Multiple Portals Using Campaign and Shop Filters

Campaign and third-party shop filters make it possible to create and maintain multiple Customer Portals for different brands, websites, stores, campaigns, or customer origins within the same RevCent account.

This is important for accounts that manage multiple ecommerce businesses, brands, shops, or websites.

Examples:

```text
Brand A Customer Portal
Brand B Customer Portal
WooCommerce Store Portal
Shopify Store Portal
Campaign-Specific Subscription Portal
Payment Recovery Portal for Website A
```

Each portal can have its own:

- Name
- Display name
- Footer HTML
- SMTP email copy
- Customer permissions
- Customer filters
- Embedded iframe placement
- Customer-facing support links
- Payment recovery strategy
- Subscription/trial self-service strategy

This allows customers to see a portal experience that matches the brand, website, or store where they purchased or originated.

---

## Editing Campaign Filters

Use `customer_filters.campaign` when portal access should be limited to customers associated with one or more campaigns.

Example:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "customer_filters": {
    "campaign": [
      "BRAND_A_CAMPAIGN_ID"
    ],
    "third_party_shop": []
  }
}
```

Meaning:

```text
Only customers associated with Brand A campaign can access this portal.
```

Use cases:

- Brand-specific portal
- Website-specific portal
- Campaign-specific portal
- Offer-specific portal
- Funnel-specific portal
- Customer acquisition source-specific portal

---

## Editing Third-Party Shop Filters

Use `customer_filters.third_party_shop` when portal access should be limited to customers associated with one or more third-party shops.

Example:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "customer_filters": {
    "campaign": [],
    "third_party_shop": [
      "STORE_A_SHOP_ID"
    ]
  }
}
```

Meaning:

```text
Only customers associated with Store A can access this portal.
```

Use cases:

- WooCommerce-specific portal
- Shopify-specific portal
- Website-specific portal
- Store-specific portal
- Brand-specific portal
- Multi-shop customer access control

---

# `customer_permissions`

`customer_permissions` determines what customers can do in the portal.

Changing permissions is high impact because it changes customer self-service behavior.

Shape:

```json
"customer_permissions": {
  "contact_modify": true,
  "credit_card_add": true,
  "credit_card_remove": true,
  "credit_card_set_default": true,
  "shipping_modify_ship_to": true,
  "subscription_renew": true,
  "subscription_activate": true,
  "subscription_suspend": false,
  "subscription_cancel": false,
  "trial_expire": false,
  "trial_cancel": false,
  "salvage_transaction_process": true
}
```

Recommended behavior:

```text
When editing customer_permissions, provide the complete intended permission object.
```

Do not rely on partial nested permission merging unless the API explicitly supports it.

---

## Permission Summary

| Permission | Customer-facing meaning |
|---|---|
| `contact_modify` | Customer can modify contact information. |
| `credit_card_add` | Customer can add a payment card. |
| `credit_card_remove` | Customer can remove a payment card. |
| `credit_card_set_default` | Customer can set a default payment card. |
| `shipping_modify_ship_to` | Customer can modify shipping information. |
| `subscription_renew` | Customer can renew subscriptions. |
| `subscription_activate` | Customer can re-activate subscriptions. |
| `subscription_suspend` | Customer can suspend subscriptions. |
| `subscription_cancel` | Customer can cancel subscriptions. |
| `trial_expire` | Customer can expire trials. |
| `trial_cancel` | Customer can cancel trials. |
| `salvage_transaction_process` | Customer can pay failed renewals or failed trial expirations through the portal. |

---

## High-Risk Permission: `subscription_cancel`

`subscription_cancel` allows customers to cancel subscriptions directly through the portal.

Only set this to `true` if the business explicitly wants customers to self-cancel subscriptions.

If cancellation should require support, retention review, AI Voice Agent save workflow, or manual approval, keep:

```json
"subscription_cancel": false
```

---

## Important System Term: `salvage_transaction_process`

`salvage_transaction_process` is a RevCent system term.

Customer-facing meaning:

```text
Customer can pay failed renewals or failed trial expirations through the portal.
```

Use cases:

- Failed renewal payment recovery
- Failed trial expiration recovery
- Customer self-service payment resolution
- Revenue recovery without manual support intervention

Do not describe this to customers as “process salvage transaction.”

Use customer-friendly wording such as:

```text
Pay failed renewal
Resolve failed trial expiration
Complete overdue payment
Update payment and retry billing
```

---

# `create_non_existing_customer`

`create_non_existing_customer` determines whether non-existing customers can register for the portal.

Recommended setting:

```json
"create_non_existing_customer": false
```

Editing this to `true` is high risk.

If enabled, customers who do not already exist may be able to register through the portal.

Only enable if the business intentionally wants non-existing customer registration.

---

# `create_non_existing_customer_campaign`

If `create_non_existing_customer` is true, this field determines the campaign ID assigned to non-existing customers who register through the portal.

Example:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "create_non_existing_customer": true,
  "create_non_existing_customer_campaign": "YYYYYYYYYYYYYYYYYYYY"
}
```

Requirements:

- Must be a 20-character campaign ID.
- Only relevant when `create_non_existing_customer` is true.
- Should be intentionally selected by the business.

---

# Example Requests

## Rename Portal Only

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "name": "Brand A Customer Portal"
}
```

---

## Disable Portal

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

---

## Enable Portal

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

Only enable after domain, SSL, SMTP, email templates, reCAPTCHA, filters, and permissions are verified.

---

## Update Display Name and Footer

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "display_name": "Manage Your Brand A Account",
  "footer_html": "<p>Need help? Contact support@brand-a.example.</p>"
}
```

---

## Update Customer Filters for Brand A

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "customer_filters": {
    "campaign": [
      "BRAND_A_CAMPAIGN_ID"
    ],
    "third_party_shop": []
  }
}
```

---

## Update Customer Filters for Store A

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "customer_filters": {
    "campaign": [],
    "third_party_shop": [
      "STORE_A_SHOP_ID"
    ]
  }
}
```

---

## Update Customer Permissions

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "customer_permissions": {
    "contact_modify": true,
    "credit_card_add": true,
    "credit_card_remove": true,
    "credit_card_set_default": true,
    "shipping_modify_ship_to": true,
    "subscription_renew": true,
    "subscription_activate": true,
    "subscription_suspend": false,
    "subscription_cancel": false,
    "trial_expire": false,
    "trial_cancel": false,
    "salvage_transaction_process": true
  }
}
```

---

## Update Customer Emails

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "customer_emails": {
    "customer_account_confirm_email": {
      "from": "support@example.com",
      "from_name": "Example Store",
      "subject": "Confirm your customer portal account",
      "html": "<p>Your confirmation code is: <strong>{{email_code}}</strong></p>",
      "to_cc": [],
      "to_bcc": []
    },
    "customer_account_password_reset": {
      "from": "support@example.com",
      "from_name": "Example Store",
      "subject": "Reset your customer portal password",
      "html": "<p>Your password reset code is: <strong>{{email_code}}</strong></p>",
      "to_cc": [],
      "to_bcc": []
    }
  }
}
```

---

# MCP Questions Before Editing

Before calling `EditCustomerPortal`, MCP should determine:

1. Which Customer Portal should be edited?
2. What is the `customer_portal_id`?
3. Which exact fields need to change?
4. Is this a simple name/description/display edit?
5. Is the portal being enabled or disabled?
6. Is the tracking domain changing?
7. If domain changes, is the new tracking domain DNS ready and SSL active?
8. Is reCAPTCHA changing?
9. If reCAPTCHA changes, are keys valid for the portal domain?
10. Is SMTP Profile changing?
11. If SMTP changes, are sender emails compatible?
12. Are customer emails changing?
13. If emails change, do both templates include `{{email_code}}`?
14. Are customer filters changing?
15. Should the portal be global or brand/shop/campaign-specific?
16. Does this RevCent account contain multiple brands, websites, or shops?
17. Are customer permissions changing?
18. Should customers be allowed to cancel subscriptions?
19. Should customers be allowed to pay failed renewals or failed trial expirations?
20. Should non-existing customer registration remain disabled?
21. Should the portal be disabled while the change is reviewed?
22. Could this edit affect live customers?

---

# MCP Validation Checklist

Before submitting `EditCustomerPortal`:

1. `customer_portal_id` is present and is a 20-character ID.
2. Only fields being modified are included.
3. No unknown fields are included.
4. If `name` is included, it is unique and clear.
5. If `enabled` is true, the portal is ready for customers.
6. If `tracking_domain` is included, it is 20 characters.
7. If `tracking_domain` is included, domain is DNS ready and SSL active.
8. If `recaptcha` is included, both `site_key` and `secret_key` are included.
9. If `recaptcha` is included, keys match the portal domain.
10. If `smtp_profile` is included, it is a valid 20-character SMTP Profile ID.
11. If `customer_emails` is included, both email objects are present.
12. If `customer_emails` is included, both email objects include `from`, `from_name`, `subject`, `html`, `to_cc`, and `to_bcc`.
13. If `customer_emails` is included, both HTML templates include `{{email_code}}`.
14. If `customer_filters` is included, campaign IDs are 20 characters.
15. If `customer_filters` is included, third-party shop IDs are 20 characters.
16. For multi-brand or multi-shop accounts, campaign/shop filters have been considered.
17. If `customer_permissions` is included, permissions are intentionally set.
18. `subscription_cancel` is true only if direct customer cancellation is intended.
19. `salvage_transaction_process` is true only if customers should pay failed renewals or failed trial expirations.
20. `create_non_existing_customer` is false unless intentionally needed.
21. If `create_non_existing_customer` is true, `create_non_existing_customer_campaign` is present and 20 characters.
22. High-risk edits have been reviewed.
23. Portal has been disabled first if needed for safe review/testing.

---

# Common Mistakes

## Mistake: Sending Full Portal Object for a Simple Edit

Wrong:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "name": "Updated Name",
  "customer_permissions": {},
  "customer_filters": {}
}
```

Correct:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "name": "Updated Name"
}
```

---

## Mistake: Removing Customer Filters Accidentally

If `customer_filters` is replaced with empty arrays, all customers may be able to access the portal.

Make sure this is intentional.

---

## Mistake: Missing `{{email_code}}`

Both customer email templates need:

```handlebars
{{email_code}}
```

Do not update email HTML without it.

---

## Mistake: Changing Domain Without reCAPTCHA Review

If the tracking domain changes, reCAPTCHA keys may also need to change.

---

## Mistake: Enabling Subscription Cancellation Accidentally

If customers should not cancel subscriptions directly:

```json
"subscription_cancel": false
```

---

## Mistake: Misunderstanding `salvage_transaction_process`

Wrong customer-facing explanation:

```text
Customer can process a salvage transaction.
```

Correct customer-facing explanation:

```text
Customer can pay failed renewals or failed trial expirations through the portal.
```

---

## Mistake: Enabling Non-Existing Customer Registration Accidentally

Recommended:

```json
"create_non_existing_customer": false
```

Only enable intentionally.

---

# Output Schema

Successful response:

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

| Field | Description |
|---|---|
| `api_call_id` | 20-character API call ID. |
| `api_call_unix` | Unix timestamp when the call was initiated. |
| `code` | API response code. `1` indicates success. |
| `customer_portal_id` | 20-character Customer Portal ID edited by the operation. |
| `result` | Human-readable result message. |

---

# Quick Reference

Minimum edit shape:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX"
}
```

Name-only edit:

```json
{
  "customer_portal_id": "XXXXXXXXXXXXXXXXXXXX",
  "name": "Updated Portal Name"
}
```

Disable portal:

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

Most important MCP rules:

```text
EditCustomerPortal is a partial-update operation.
Only include fields being modified.
Changing tracking_domain requires DNS-ready domain with active SSL.
Changing reCAPTCHA requires both site_key and secret_key.
Changing customer_emails requires {{email_code}} in both templates.
Changing customer_filters changes which customers can access the portal.
Campaign/shop filters enable brand-, website-, store-, and purchase-origin-specific portals.
Changing customer_permissions changes what customers can do.
salvage_transaction_process means customers can pay failed renewals or failed trial expirations.
create_non_existing_customer should usually remain false.
Disable first for high-risk changes, then review/test before enabling.
```


---
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.