Configure Scheduled Webhooks
Send scheduled HTTP requests to an environment on a UTC cron schedule.
Scheduled webhooks let Phemeral send HTTP requests to one of your environments on a recurring schedule. This is useful for tasks like warming caches, triggering internal maintenance endpoints, or running application-level jobs without relying on an external cron worker.
Prerequisites
- A Phemeral project with at least one environment.
- At least one active domain on the environment you want to target.
- An application endpoint that can safely be called on a schedule.
How Scheduled Webhooks Work
Scheduled webhooks are configured from the project's Settings tab, but each webhook targets a single environment.
When a scheduled webhook runs, Phemeral:
- Resolves the selected environment's oldest active domain.
- Sends the configured HTTP request to the relative path you provided.
- Routes that request to the environment's current deployment.
This means the webhook follows the environment as new deployments become current. You do not need to update the webhook after each deployment.
Add a Scheduled Webhook
- Open your project in the dashboard.
- Go to the Settings tab.
- Find the Scheduled Webhooks section.
- Click Add Scheduled Webhook.
- Enter a name.
- Select the environment to target.
- Enter the relative path to call, such as
/api/cron/daily. - Choose the HTTP method.
- Enter a UTC 6-field cron expression.
- Optionally configure headers, a request body, expected status codes, a start time, an end time, retries, or the disabled state.
- Save the webhook.
If the selected environment does not have an active domain, Phemeral blocks the save until one is available.
Cron Format
Scheduled webhooks use a UTC 6-field cron expression in 6 field format:
second minute hour day-of-month month day-of-weekExamples:
| Schedule | Expression |
|---|---|
| Every 30 seconds | */30 * * * * * |
| Every hour at minute 15 | 0 15 * * * * |
| Every day at 03:00 UTC | 0 0 3 * * * |
| Every Monday at 09:30 UTC | 0 30 9 * * 1 |
All cron expressions are interpreted in UTC.
Optional Request Controls
You can customize how Phemeral executes each scheduled webhook with the following optional settings:
- Headers: Add custom request headers.
- Body: Send a request body for methods like
POST,PUT, orPATCH. - Expected status codes: Provide a comma-separated list such as
200,201,204. Any other response is treated as a failed execution. - Retries: Retry failed executions a fixed number of times.
- Starts at / Expires at: Limit when the schedule is active using UTC ISO 8601 timestamps such as
2026-05-01T00:00:00Z. - Disabled: Keep the webhook saved without running it.
If you leave Expected status codes empty, Phemeral accepts any HTTP status code as a successful execution.
Edit, Disable, or Delete a Scheduled Webhook
- Open the project's Settings tab.
- In Scheduled Webhooks, find the webhook you want to change.
- Choose one of the following:
- Edit to update the request configuration or schedule.
- Disable from the edit dialog to keep the webhook without executing it.
- Delete to remove it entirely.
Changes take effect on future runs. Deleting a scheduled webhook stops future executions.
Environment Domain Behavior
Scheduled webhooks require an active environment domain.
- New webhooks cannot be saved unless the selected environment has at least one active domain.
- Phemeral always targets the environment's oldest active domain.
- If the active domain set changes, Phemeral resyncs the webhook to the current canonical active domain.
- If an environment temporarily has no active domains, the scheduled webhook remains saved but does not run until an active domain is available again.
Observing Scheduled Webhook Traffic
Scheduled webhook requests are normal HTTP requests to your application. You can inspect their effects in the same places you inspect other traffic:
- Runtime logs on the deployment detail page.
- Application-specific logs emitted by the endpoint you called.
- Any side effects produced by your handler, such as cache refreshes or background task creation.
Because the request is routed through the environment's current deployment, the runtime logs appear on the deployment that actually handled the request.