---
schema_version: "1"
id: e4ea199d43742462d2f56ef534451c43a338bc0637799766eab6dead966c77cb
title: IAccountManagementDELETE Apex Interface
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/industries-integrations/comms/guides/Extensibility/TMF666/IAccountManagementDELETE.md
canonical_url: https://developer.salesforce.com/docs/industries/communications/guide/IAccountManagementDELETE.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 0ab51e4c70aa1a4ecc88e8e3106181422ec7a81447c22a7f1f4389fa000a934b
products:
  - Communications Cloud TM Forum API
  - Industries Integrations
---
# IAccountManagementDELETE Apex Interface

The IAccountManagementDELETE interface provides extensibility for DELETE operations through Apex-based validations, mutation-payload adjustments, and post-operation processing. Users can enforce deletion policies, apply soft-delete or metadata logic, and customize final responses without impacting TMF-compliant delete behavior.

This interface supports the following hooks.

- [transformRequest](#transformrequest)
- [applyCustomValidations](#applycustomvalidations)
- [customiseMutationPayload](#customisemutationpayload)
- [handlePostOperation](#handlepostoperation)

**note:** The `customiseGraphQLQuery` is not applicable to DELETE, which is a write operation, so there is no read query to customize. This hook is declared on the read interface (`ICommsGET`), not on `ICommsDELETE`. To customize the soft-delete mutation payload, use `customiseMutationPayload`.

## Account Delete Operation Use Cases

| **Use Case**                                       | **Hook(s)**                                | **Description**                                                                                                                                                                                           | **Example Scenarios**                                                                                                                                                                                                           | **Benefit**                                                                                                                                               |
| -------------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Resolve an External Key to the Salesforce ID**   | `transformRequest`                         | Resolves a caller-provided business key or external identifier to the canonical Salesforce Account ID before validation and deletion processing begins.                                                   | - Resolve an ERP customer number <br>- Map a billing-system identifier to an Account ID<br>- Translate a partner-specific key <br>- Resolve a legacy account reference                                                          | Allows callers to address Account records using their own identifiers instead of requiring a Salesforce ID.                                               |
| **Block Deletion Based on Business Preconditions** | `applyCustomValidations`                   | Evaluates business rules and dependent-record conditions before the delete mutation is built. The operation is rejected when the Account does not satisfy the required deletion criteria.                 | - Prevent deletion when active subscriptions exist <br>- Block deletion when the Account has an open balance <br>- Reject deletion when active contracts or orders exist <br>- Protect Accounts involved in unresolved disputes | Prevents invalid deletion or deactivation of Accounts that still have active financial, contractual, or operational obligations.                          |
| **Capture a Deactivation Reason or Audit Field**   | `customiseMutationPayload` (`addFields`)   | Adds organization-specific fields to the mutation payload without replacing the standard delete input. These fields can capture the reason, actor, source, or timestamp associated with the deactivation. | - Store a deactivation reason code <br>- Record the user who initiated the operation <br>- Add a deactivation timestamp <br>- Capture the originating channel or system                                                         | Records why and how the Account was deactivated, improving traceability and operational reporting.                                                        |
| **Override the Terminal Status**                   | `customiseMutationPayload` (`modifyInput`) | Modifies the standard mutation input to use an organization-specific terminal status instead of the default soft-delete status.                                                                           | - Set the status to `Cancelled`<br>- Use `Closed` for completed Account relationships<br>- Apply a region-specific terminal state <br>- Select a status based on Account type                                                   | Aligns soft-delete behavior with organization-specific lifecycle models by using `Cancelled`, `Closed`, or another terminal status instead of `Inactive`. |
| **Cascade Cleanup or Deprovisioning**              | `handlePostOperation`                      | Runs after the Account mutation completes and uses the operation result to clean up related resources or initiate downstream deprovisioning.                                                              | - Deactivate Account-contact junctions <br>- Revoke associated entitlements <br>- Disable downstream access or services <br>- Publish a deprovisioning event<br>- Notify billing or subscription systems                        | Keeps related records and downstream systems consistent with the Account's deactivated state.                                                             |
| **Create an Audit Trail**                          | `handlePostOperation`                      | Records the completed deletion or deactivation in an audit or compliance system after the mutation succeeds.                                                                                              | - Write a compliance audit entry <br>- Record the actor, timestamp, and affected Account <br>- Store the mutation result and deactivation reason <br>- Publish an immutable deletion event                                      | Provides a reliable compliance record of Account deletions and deactivations.                                                                             |

## transformRequest

This hook transforms the request context before processing any operation. It is invoked early in the request lifecycle, allowing implementers to adjust the context for subsequent extensibility hooks.

## Hook Method

`Map<String, Object> transformRequest(Map<String, Object> context)`

## Sample Apex Implementation

Resolve an external ID to a Salesforce Contact ID.

```
global class AccountMgmtTransformRequestDeleteExt implements comms_apex_ext.IAccountManagementDELETE {


    global static Map<String, Object> transformRequest(Map<String, Object> context) {
        if (context == null) {
            return context;
        }


        // If the caller addressed the record by an external key, resolve it to the SF id.
        Object idObj = context.get('id');
        if (idObj instanceof String && ((String) idObj).startsWith('EXT-')) {
            String externalKey = (String) idObj;
            List<BillingAccount> matches = [
                SELECT Id FROM BillingAccount WHERE ExtlBillingAccountId__c = :externalKey LIMIT 1
            ];
            if (!matches.isEmpty()) {
                context.put('id', matches[0].Id);
            }
        }
        return context;
    }


    // ... other hooks return null / empty map ...
}

```

## applyCustomValidations

This hook validates custom business logic before retrieving customer record. If validation fails, it rejects the request and returns an error response.

The handler processes return values as follows.

Success:

- Return a map with validationStatus set to "pass" (case-insensitive).
- The API request continues normally.
- Other fields in the map are logged but not used.

Failure:

- Return a map with validationStatus set to "fail" (case-insensitive).
- The API request is terminated immediately.
- Raise a ValidationException containing
  - message: value from validationMessage key (or "Validation failed" by default)
  - details: value from validationDetails key (optional)
- The client receives an HTTP 400 error response.

## Hook Method

`Map<String, Object> applyCustomValidations(Map<String, Object> context)`

## Sample Apex Implementation

Block deletion when the Account has active subscriptions.

```
global class AccountMgmtCustomValidationDeleteExt implements comms_apex_ext.IAccountManagementDELETE {


    global static Map<String, Object> applyCustomValidations(Map<String, Object> context) {
        Map<String, Object> result = new Map<String, Object>();
        String billingAccountId = (String) context.get('id');


        if (billingAccountId != null) {
            Integer activeCount = [
                SELECT COUNT() FROM Order
                WHERE BillingAccountId = :billingAccountId AND Status = 'Activated'
            ];
            if (activeCount > 0) {
                result.put('validationStatus', 'fail');
                result.put('validationMessage',
                    'Cannot delete a billing account with active subscriptions.');
                result.put('validationDetails', new Map<String, Object>{
                    'billingAccountId'    => billingAccountId,
                    'activeSubscriptions' => activeCount,
                    'rule'                => 'NO_DELETE_WITH_ACTIVE_SUBS'
                });
                return result;
            }
        }


        result.put('validationStatus', 'pass');
        return result;
    }
    // ... other hooks return null / empty map ...
}

```

## customiseMutationPayload

This hook modifies the mutation payload before deleting a customer record. Use this to add deletion metadata, set soft-delete flags, or apply business logic transformations.

## Hook Method

`Map<String, Object> customiseMutationPayload(Map<String, Object> request, Map<String, Object> context)`

## Sample Apex Implementation

Add a custom field alongside the Status = Inactive change so the soft delete captures why the account was deactivated.

```
global class AccountMgmtMutationPayloadDeleteExt implements comms_apex_ext.IAccountManagementDELETE {


    global static Map<String, Object> customiseMutationPayload(
        Map<String, Object> mutationGraphQLPayload,
        Map<String, Object> context
    ) {
        Map<String, Object> node = new Map<String, Object>{
            'path'      => 'softDeleteBillingAccount',
            'addFields' => new Map<String, Object>{
                'ExtlDeactivationReason__c' => 'Deleted via TMF666 API'
            }
        };
        return new Map<String, Object>{ 'nodes' => new List<Object>{ node } };
    }


    // ... other hooks return null / empty map ...
}

```

## handlePostOperation

This hook post-processes and transforms the API response after data retrieval.

## Hook Method

`Map<String, Object> handlePostOperation(Map<String, Object> graphQLQueryResultAsMap, Map<String, Object> constructedTMFResponse, Map<String, Object> context)`

## Sample Apex Implementation

Audit-log the soft delete and cascade cleanup.

```
global class IndividualDeleteHandlePostOpExt implements comms_apex_ext.IIndividualPartyManagementDELETE {


    global static Map<String, Object> handlePostOperation(
        Map<String, Object> graphQLQueryResultAsMap,
        Map<String, Object> constructedTMFResponse,
        Map<String, Object> context
    ) {
        Object dr = context != null ? context.get('deleteResult') : null;
        if (dr instanceof Map<String, Object>) {
            Map<String, Object> deleteResult = (Map<String, Object>) dr;
            if (Boolean.TRUE.equals(deleteResult.get('success'))) {
                insert new Individual_Deletion_Log__c(
                    Individual_Id__c = (String) deleteResult.get('deletedId'),
                    Deleted_By__c    = UserInfo.getUserId()
                );
            }
        }
        return null;   // no body for HTTP 204
    }


    // customiseMutationPayload still REQUIRED — see HOOK 4 ...
}

```

## Full Implementation Example

Here's a complete sample Apex implementation using all supported hooks.

```
global class AccountMgmtPostOpAuditDeleteExt implements comms_apex_ext.IAccountManagementDELETE {


    global static Map<String, Object> handlePostOperation(
        Map<String, Object> graphQLResult,
        Map<String, Object> deleteResult,
        Map<String, Object> context
    ) {
        try {
            Boolean success = deleteResult != null
                && Boolean.TRUE.equals(deleteResult.get('success'));
            String deletedId = deleteResult != null
                ? (String) deleteResult.get('deletedId')
                : (String) context.get('id');


            System.debug('BillingAccount soft-deleted via TMF666 DELETE by '
                + UserInfo.getName() + ': ' + deletedId + ' (success=' + success + ')');


            // Example cascade: mark related junction records inactive (bulk-safe single DML).
            if (success && deletedId != null) {
                // ... enqueue or perform cleanup keyed on deletedId ...
            }
        } catch (Exception e) {
            System.debug('Post-delete handling failed: ' + e.getMessage());
        }
        // Return value is ignored for DELETE.
        return null;
    }


    // ... other hooks return null / empty map ...
}


```
