Moderation Appeal Escalation

Escalation workflow for content moderation appeals. Applies a review hold, runs parallel senior review and classifier audit, then routes to reinstatement or upheld rejection.
{
  "Comment": "Escalation workflow for content moderation appeals. Applies a review hold, runs parallel senior review and classifier audit, then routes to reinstatement or upheld rejection.",
  "StartAt": "SetAppealContext",
  "States": {
    "SetAppealContext": {
      "Type": "Pass",
      "Parameters": {
        "contentId.$": "$.contentId",
        "contentType.$": "$.contentType",
        "platform.$": "$.platform",
        "source.$": "$.source",
        "submittedBy.$": "$.submittedBy",
        "metadata.$": "$.metadata",
        "rawContent.$": "$.rawContent",
        "appealContext": {
          "appealId": "APPEAL-2026-00847",
          "appealReason": "INCORRECTLY_CLASSIFIED",
          "appealSubmittedAt": "2026-04-26T09:00:00Z",
          "originalActionType": "CONTENT_REMOVED",
          "originalViolation": "HATE_SPEECH",
          "escalationLevel": "SENIOR_TRUST_AND_SAFETY"
        }
      },
      "Next": "ReIngestAppealContent"
    },
    "ReIngestAppealContent": {
      "Type": "Task",
      "Resource": "${IngestContentFunctionArn}",
      "Retry": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "IntervalSeconds": 2,
          "MaxAttempts": 2,
          "BackoffRate": 2
        }
      ],
      "Catch": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "Next": "AppealEscalationFailed"
        }
      ],
      "Next": "ReClassifyAppealContent"
    },
    "ReClassifyAppealContent": {
      "Type": "Task",
      "Resource": "${ClassifyContentFunctionArn}",
      "Retry": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "IntervalSeconds": 2,
          "MaxAttempts": 2,
          "BackoffRate": 2
        }
      ],
      "Catch": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "Next": "AppealEscalationFailed"
        }
      ],
      "Next": "WaitForSeniorReviewPanel"
    },
    "WaitForSeniorReviewPanel": {
      "Type": "Wait",
      "Seconds": 5,
      "Next": "ParallelSeniorReviewAndAudit"
    },
    "ParallelSeniorReviewAndAudit": {
      "Type": "Parallel",
      "Branches": [
        {
          "StartAt": "EscalatedSeniorHumanReview",
          "States": {
            "EscalatedSeniorHumanReview": {
              "Type": "Task",
              "Resource": "${HumanReviewQueueFunctionArn}",
              "Retry": [
                {
                  "ErrorEquals": [
                    "States.ALL"
                  ],
                  "IntervalSeconds": 2,
                  "MaxAttempts": 2,
                  "BackoffRate": 2
                }
              ],
              "End": true
            }
          }
        },
        {
          "StartAt": "EscalatedClassifierAudit",
          "States": {
            "EscalatedClassifierAudit": {
              "Type": "Task",
              "Resource": "${UpdateClassifierFeedbackFunctionArn}",
              "Retry": [
                {
                  "ErrorEquals": [
                    "States.ALL"
                  ],
                  "IntervalSeconds": 2,
                  "MaxAttempts": 2,
                  "BackoffRate": 2
                }
              ],
              "End": true
            }
          }
        }
      ],
      "Catch": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "Next": "AppealEscalationFailed"
        }
      ],
      "Next": "EscalatedModerationDecision"
    },
    "EscalatedModerationDecision": {
      "Type": "Task",
      "Resource": "${ApplyModerationActionFunctionArn}",
      "Retry": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "IntervalSeconds": 2,
          "MaxAttempts": 2,
          "BackoffRate": 2
        }
      ],
      "Catch": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "Next": "AppealEscalationFailed"
        }
      ],
      "Next": "NotifyAppealOutcome"
    },
    "NotifyAppealOutcome": {
      "Type": "Task",
      "Resource": "${NotifyModerationOutcomeFunctionArn}",
      "Retry": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "IntervalSeconds": 2,
          "MaxAttempts": 2,
          "BackoffRate": 2
        }
      ],
      "Next": "RouteAppealOutcome"
    },
    "RouteAppealOutcome": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.enforcement.action",
          "StringEquals": "CONTENT_APPROVED",
          "Next": "AppealGrantedContentRestored"
        }
      ],
      "Default": "AppealDeniedActionUpheld"
    },
    "AppealGrantedContentRestored": {
      "Type": "Succeed"
    },
    "AppealDeniedActionUpheld": {
      "Type": "Fail",
      "Error": "AppealDenied",
      "Cause": "Appeal reviewed by senior panel. Original moderation action upheld."
    },
    "AppealEscalationFailed": {
      "Type": "Fail",
      "Error": "AppealEscalationFailed",
      "Cause": "Appeal escalation workflow encountered an error. Manual review required."
    }
  }
}
JSON
Expand

100%

AI teams can use patterns like this to build reliable, compliant, and scalable automation for payment systems and can test and refine these flows locally with Thrubit to reduce cloud cost and speed up iteration.

Free Trial