{
"Comment": "Content takedown: validates a takedown request, waits a short cooling-off period, then runs moderation and license compliance checks in parallel before unpublishing (or failing if no violation is confirmed).",
"StartAt": "SetTakedownDefaults",
"States": {
"SetTakedownDefaults": {
"Type": "Pass",
"Parameters": {
"contentId.$": "$.contentId",
"reason.$": "$.reason",
"requestedBy.$": "$.requestedBy",
"requestedAt.$": "$.requestedAt",
"internalNote": "Takedown workflow initiated",
"takedownStatus": "PENDING"
},
"Next": "ValidateTakedownRequest"
},
"ValidateTakedownRequest": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "${ValidateContentFunctionArn}",
"Payload.$": "$"
},
"ResultPath": "$.validation",
"Retry": [
{
"ErrorEquals": [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException"
],
"IntervalSeconds": 2,
"MaxAttempts": 2,
"BackoffRate": 2
}
],
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"ResultPath": "$.error",
"Next": "TakedownFailed"
}
],
"Next": "IsTakedownEligible"
},
"IsTakedownEligible": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.validation.Payload.isValid",
"BooleanEquals": true,
"Next": "CoolingOffPeriod"
}
],
"Default": "TakedownFailed"
},
"CoolingOffPeriod": {
"Type": "Wait",
"Comment": "Brief cooling-off pause before executing the takedown to allow any in-flight operations to settle.",
"Seconds": 3,
"Next": "ComplianceVerification"
},
"ComplianceVerification": {
"Type": "Parallel",
"Comment": "Confirm the violation exists via moderation and license checks before unpublishing.",
"Branches": [
{
"StartAt": "TakedownModerationCheck",
"States": {
"TakedownModerationCheck": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "${ContentModerationFunctionArn}",
"Payload.$": "$"
},
"End": true
}
}
},
{
"StartAt": "TakedownLicenseCheck",
"States": {
"TakedownLicenseCheck": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "${LicenseCheckFunctionArn}",
"Payload.$": "$"
},
"End": true
}
}
}
],
"ResultPath": "$.complianceResult",
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"ResultPath": "$.error",
"Next": "TakedownFailed"
}
],
"Next": "IsViolationConfirmed"
},
"IsViolationConfirmed": {
"Type": "Choice",
"Choices": [
{
"Or": [
{
"Variable": "$.complianceResult[0].Payload.isViolation",
"BooleanEquals": true
},
{
"Variable": "$.complianceResult[1].Payload.isCleared",
"BooleanEquals": false
}
],
"Next": "UnpublishContent"
}
],
"Default": "TakedownFailed"
},
"UnpublishContent": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "${RejectContentFunctionArn}",
"Payload": {
"reason": "DMCA_TAKEDOWN",
"contentId.$": "$.contentId",
"requestedBy.$": "$.requestedBy",
"requestedAt.$": "$.requestedAt",
"complianceResult.$": "$.complianceResult"
}
},
"ResultPath": "$.unpublish",
"Retry": [
{
"ErrorEquals": [
"States.ALL"
],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 2
}
],
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"ResultPath": "$.error",
"Next": "TakedownFailed"
}
],
"Next": "TakedownComplete"
},
"TakedownComplete": {
"Type": "Succeed"
},
"TakedownFailed": {
"Type": "Fail",
"Error": "TakedownError",
"Cause": "Content takedown could not be completed — violation not confirmed or upstream error"
}
}
}JSONExpand
100%
Entertainment 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.