How to run a Lambda function on a schedule with EventBridge

Use EventBridge Scheduler to invoke a Lambda function on a cron or rate schedule. For a daily AI video, key the run to the scheduled time and return.

6 min readSume
All posts

To run a Lambda function on a schedule, create an Amazon EventBridge Scheduler schedule that targets the function, with a cron or rate expression evaluated in the time zone you choose; EventBridge Scheduler then invokes the function asynchronously at each time. For a scheduled AI video, the function starts a Sume run with an Idempotency-Key built from the scheduled time, returns in seconds, and takes the finished video by webhook.

AWS facts come from the Lambda and EventBridge Scheduler docs listed under Sources, starting with Invoke a Lambda function on a schedule; Sume facts come from Create a run, Runs and results, and Scheduled. All were read on 2026-09-27. Sume has no AWS integration: the function makes one plain HTTPS call. The same pattern on Vercel is Vercel Cron Jobs: call the Sume API daily.

Which schedule expression runs a Lambda every hour or every day?

A cron expression has six fields: minutes, hours, day-of-month, month, day-of-week, and year. You can't use * in both day fields, so put ? in one. Schedules fire with 60-second precision, and in a zone with daylight saving time, a time skipped in spring doesn't run that day while a repeated time in fall runs once.

From EventBridge Scheduler's Schedule types page, read 2026-09-27.
GoalExpressionNotes
Every hour, on the hourcron(0 * * * ? *)? in day-of-week, since day-of-month is *
Every day at 8:30 a.m.cron(30 8 * * ? *)Add --schedule-expression-timezone "America/New_York" or another IANA time zone
Every 5 minutesrate(5 minutes)Rate units are minutes, hours, or days
Onceat(2026-10-01T09:00:00)A one-time schedule; AWS recommends deleting it after it runs

How do I create the schedule and pass the scheduled time?

In the Lambda console, choose Add trigger, then Scheduler. With the AWS CLI, the function's ARN makes it a templated Lambda target, and the schedule's execution role needs lambda:InvokeFunction. Put <aws.scheduler.scheduled-time> in the input: EventBridge Scheduler replaces it with the time you specified for the invocation, such as 2022-03-22T18:59:43Z, while <aws.scheduler.execution-id> is unique to each attempt and would make a useless key.

aws scheduler create-schedule --name daily-recap-video \
  --schedule-expression "cron(0 9 * * ? *)" \
  --schedule-expression-timezone "America/New_York" \
  --flexible-time-window '{ "Mode": "OFF" }' \
  --target '{ "RoleArn": "ROLE_ARN", "Arn": "FUNCTION_ARN",
    "Input": "{ \"scheduled_time\": \"<aws.scheduler.scheduled-time>\" }" }'

What should the function send to the Sume API?

One POST /v1/formats/{handle}/{slug}/runs with the day's data in input, keyed to the scheduled time. input is yours to shape, up to 64 top-level keys and 2 MiB; build it from data that is fixed for that slot, so a retry sends the same body. urlopen raises HTTPError on an error status, which fails the invocation. The snippet reads the key from an environment variable for brevity; AWS recommends Secrets Manager for API keys.

import json, os, urllib.request

def lambda_handler(event, context):
    slot = event["scheduled_time"]  # the same value on every retry of this slot
    body = {
        "input": {"scheduled_time": slot, "totals": totals_for(slot)},  # fixed per slot
        "communication": {"webhook_url": "https://example.com/hooks/sume"},
    }
    req = urllib.request.Request(
        "https://api.sume.com/v1/formats/acme/daily-recap/runs",
        data=json.dumps(body).encode(),
        headers={
            "Authorization": f"Bearer {os.environ['SUME_API_KEY']}",
            "Content-Type": "application/json",
            "Idempotency-Key": f"daily-recap-{slot}",
        },
        method="POST",
    )
    with urllib.request.urlopen(req, timeout=10) as resp:
        run = json.load(resp)["data"]  # 202 new run, 200 replay
    return {"run_id": run["id"], "replay": run["idempotency_hit"]}

What happens when the invocation runs twice?

Nothing new, as long as the key comes from the scheduled time. Repeats do happen: if the function returns an error, Lambda runs it two more times by default, one minute and then two minutes apart, and timeouts count as errors. Even without an error, the asynchronous queue can deliver the same event more than once, so AWS asks you to handle duplicates. EventBridge Scheduler also has a RetryPolicy for delivering to the target, allowing up to 185 retry attempts and an event age of up to 86,400 seconds. With the same key, Sume answers each repeat like this:

  • Same key, same body: 200 with the original receipt and idempotency_hit: true. No second run, no second charge.
  • Same key, different body: 409 idempotency_conflict, and nothing runs.
  • Same key at the same moment: one wins; the other gets 409 idempotency_key_in_use, retryable after about a second.
  • After a failed create (402, 503, …), the key is released, so the retry can still start the run.

Should the function wait for the video?

No. A Lambda timeout defaults to 3 seconds, below the snippet's 10-second urlopen timeout, so raise it enough for the submit. Waiting for the video is another matter: the maximum is 900 seconds (5,400 for asynchronous invocations on Lambda Managed Instances), long-form video is 15 to 30 minutes of work, and a timeout does not cancel the run, which keeps running and billing. The webhook_url gets one signed POST when the run completes or fails; AWS Lambda webhook receiver for Sume shows that side on a function URL.

Do I need Lambda for a scheduled video at all?

Only if the run needs your data. Sume's own Scheduled feature runs a saved automation on a 5-field cron in an IANA time zone, and its docs say to reach for it when nothing triggers the work except the clock. Schedules are authored in the Agents dashboard, not over the API. Scheduled AI video agent runs covers that path.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume