A custom resource's type is AWS 24 ::CloudFormation 24 ::CustomResource or Custom:: plus a name, and its one required property, ServiceToken, is the ARN of a Lambda 24 function or SNS topic in the stack's region. ServiceTimeout (1 to 3,600 seconds, default 3,600) sets how long CloudFormation waits; other properties are yours.

The request carries RequestType (Create, Update or Delete), RequestId, StackId, LogicalResourceId, ResourceType, ResourceProperties and a ResponseURL, a presigned S3 URL; Update and Delete add your earlier PhysicalResourceId, and Update adds OldResourceProperties. The provider PUTs a JSON answer to that URL: Status (SUCCESS or FAILED), the copied RequestId, StackId and LogicalResourceId, a non-empty PhysicalResourceId, a Reason (required on failure), and optional Data, whose keys become Fn::GetAtt attributes, with NoEcho to mask them. The body may not exceed 4,096 bytes.
The physical ID is subtle: a new ID from an Update means replacement, and CloudFormation later sends a Delete for the old ID, so a provider that invents a random ID deletes its own work on every update. BookNest's seeder derives the ID from the table name.