Recuro.

How to Send Scheduled HTTP Requests (Cron + Webhooks)

·
Updated March 29, 2026
· Recuro Team
webhookshttp

Quick Summary — TL;DR

  • Scheduled HTTP requests are outbound calls your system makes on a timer — not the same as event-driven webhook delivery.
  • You can use crontab + cURL for simple setups, a framework scheduler for code-level control, a cloud-native scheduler for AWS/GCP/Azure projects, or an external HTTP scheduler for production reliability.
  • Always secure scheduled endpoints with API tokens or webhook signing, and make them idempotent.
  • Handle timezone differences carefully — prefer UTC and use a scheduler with timezone support if local time matters.
  • Test your scheduled webhooks manually before going live to catch authentication, timeout, and payload issues early.
Webhook Scheduling Send Http Requests On Schedule

Sometimes you need to hit an HTTP endpoint on a schedule. Maybe it’s an API call that triggers a data sync, a POST request that refreshes a cache, or a webhook that kicks off a daily report. Whatever the use case, you need something that fires the request on time and tells you when it doesn’t.

This is different from event-driven webhook delivery, where a service pushes a notification the moment something happens (a payment succeeds, a commit is pushed). Scheduled HTTP requests are timer-driven: you define a cron expression and the system sends the request at that interval regardless of whether any event occurred. The term “webhook scheduling” is commonly used for this pattern, but what you’re really doing is scheduling outbound HTTP requests on a recurring timer.

Here’s how to set it up — from quick and dirty to production-grade.

What is a scheduled HTTP request?

A scheduled HTTP request is an outgoing HTTP call (GET, POST, PUT, etc.) that fires at predetermined intervals. Unlike incoming webhooks (where an external service pushes data to your endpoint when an event occurs), scheduled HTTP requests are outbound and time-based — your scheduler triggers an HTTP callback on a cron expression, calling someone else’s endpoint, or your own. If you’re unclear on how webhooks differ from standard APIs, see webhooks vs APIs for a complete comparison.

Common use cases:

  • Triggering a data sync between two services every 15 minutes
  • Refreshing a CDN or cache at the top of every hour
  • Sending a daily digest by hitting your email service’s API
  • Running a cleanup task on an endpoint that archives old records
  • Pinging a health check endpoint every minute to verify uptime

Option 1: cURL + crontab (Linux/Mac)

The simplest approach — add a line to your crontab:

Terminal window
# Every hour, POST to the sync endpoint
0 * * * * curl -sf -X POST https://api.example.com/sync -H "Authorization: Bearer YOUR_TOKEN"

Adding basic error handling

Terminal window
0 * * * * curl -sf -X POST https://api.example.com/sync \
-H "Authorization: Bearer YOUR_TOKEN" \
-o /dev/null -w "%{http_code}" \
>> /var/log/sync-cron.log 2>&1

When this works

  • You have a persistent Linux/Mac server that’s always on (see crontab explained for a full guide to managing crontab)
  • You have one or two simple schedules
  • You don’t need retries or alerts

When this doesn’t work

  • Your server reboots and nobody re-enables cron
  • You need to send headers, payloads, or different HTTP methods
  • You need to know when it fails
  • You’re on a serverless platform with no crontab

Option 2: Scheduled tasks in your framework

Most web frameworks have a task scheduler:

Laravel (11+)

routes/console.php
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Schedule;
Schedule::call(function () {
Http::post('https://api.example.com/sync', [
'since' => now()->subHour(),
]);
})->hourly();

Node.js (node-cron)

import cron from 'node-cron';
cron.schedule('0 * * * *', async () => {
await fetch('https://api.example.com/sync', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_TOKEN' },
});
});

Django (Celery Beat)

celery.py
app.conf.beat_schedule = {
'hourly-sync': {
'task': 'tasks.sync',
'schedule': crontab(minute=0),
},
}

Trade-offs

Pros:

  • Scheduling lives in your codebase
  • Access to your app’s configuration and secrets

Cons:

  • Requires a persistent process (worker, scheduler daemon, or cron runner) — which means monitoring the monitor
  • If the process dies, schedules stop silently. No alerts, no indication anything is wrong. Users just stop getting emails, jobs stop syncing, reports stop generating
  • Retry logic is your responsibility — and most apps don’t implement it properly
  • No centralized view across multiple services

Option 3: Cloud-native schedulers

If you’re already on a major cloud provider, you can use their built-in scheduling services to fire HTTP requests on a cron schedule.

AWS EventBridge Scheduler lets you create one-time or recurring schedules that invoke targets including API Gateway endpoints, Lambda functions, or any HTTP endpoint via API destinations. You define the schedule as a cron or rate expression, and EventBridge handles invocation and retries.

Google Cloud Scheduler is a fully managed cron job service. You create a job with a cron expression, target URL, HTTP method, and headers. It supports retry configuration, dead-letter topics, and integrates with Pub/Sub and Cloud Functions.

Azure Logic Apps offers a recurrence trigger that fires on a schedule and can call any HTTP endpoint. You build the workflow visually or via ARM templates, with built-in retry policies and monitoring through the Azure portal.

Trade-offs

Pros:

  • Fully managed — no servers or processes to keep alive
  • Integrated with your cloud provider’s IAM, logging, and monitoring
  • Pay-per-invocation pricing at low volumes

Cons:

  • Vendor lock-in — your scheduling configuration is tied to one cloud provider. Moving to another provider means rebuilding from scratch
  • Pricing complexity — costs scale in non-obvious ways. EventBridge charges per invocation plus per state transition; Cloud Scheduler bills per job per month plus per execution; Logic Apps charges per trigger, action, and connector. At high volumes, costs can surprise you
  • Fragmented visibility — each cloud scheduler has its own dashboard. If you have schedules across multiple services or providers, there’s no single view
  • Configuration overhead — setting up IAM roles, API destinations, and VPC connectivity for a simple HTTP call can take longer than the call itself

Cloud schedulers are a reasonable choice if you’re already deep in one ecosystem and your schedules target services within the same cloud. For cross-cloud or cross-service scheduling, the operational overhead often outweighs the benefits.

Option 4: External HTTP scheduler

An external scheduler takes a different approach: you define what to call and when, and the scheduler handles execution, retries, and monitoring independently of your application — regardless of where your endpoints live.

What you configure

FieldExample
URLhttps://api.example.com/sync
MethodPOST
HeadersAuthorization: Bearer YOUR_TOKEN
Payload{"since": "1h"}
Schedule0 * * * * (every hour)
Timeout30 seconds
Retries3

What the scheduler handles

  • Execution — sends the HTTP request at the scheduled time
  • Retries — if the request fails, retries with exponential backoff
  • Logging — records every execution with status code, response time, and body
  • Alerts — notifies you when consecutive failures exceed your threshold
  • Recovery — notifies you when a failing job starts succeeding again

Comparing your options

Crontab + cURLFramework schedulerCloud schedulerExternal HTTP scheduler
Setup complexityLow — one line in crontabMedium — requires app code and a persistent processMedium — IAM roles, API destinations, cloud configLow — web UI or API to define URL, method, and schedule
ReliabilityLow — dies with the server, no retriesMedium — depends on your process staying aliveHigh — managed by cloud providerHigh — independent of your infrastructure
RetriesNoneManual implementationConfigurable but provider-specificBuilt-in with exponential backoff
MonitoringNone — check logs manuallyDIY loggingCloud-native dashboardsExecution logs, failure alerts, recovery alerts
CostFree (if you already have a server)Free (if you already run the app)Pay-per-invocation — can get complexSubscription-based — predictable
Vendor lock-inNoneTied to your frameworkTied to your cloud providerNone — calls any HTTP endpoint
Multi-service visibilityNonePer-app onlyPer-cloud onlySingle dashboard across all endpoints

For one or two simple schedules on a server you already manage, crontab works. For schedules tightly coupled to application logic, a framework scheduler makes sense. For everything else — especially when you need reliability, retries, and visibility across multiple services — a cloud scheduler or external HTTP scheduler is the more practical choice.

Sending custom headers and payloads

Many scheduled HTTP requests need authentication headers or a JSON payload. Make sure your scheduling solution supports:

  • Custom headersAuthorization, Content-Type, X-Api-Key, etc.
  • Request body — JSON payloads for POST/PUT/PATCH requests
  • HTTP methods — not just GET, but POST, PUT, PATCH, and DELETE

If you’re using crontab + cURL, this means long, fragile command lines. A managed scheduler gives you a form or API to configure these cleanly.

Handling failures

HTTP requests fail. Networks are unreliable, servers go down, and deployments break endpoints. Your scheduling setup needs to handle this gracefully:

  1. Retry with backoff — don’t hammer a failing endpoint. Wait 30 seconds, then 1 minute, then 2 minutes.
  2. Set a timeout — don’t let a hung connection block the next execution. 30 seconds is a reasonable default.
  3. Alert on repeated failures — a single timeout is normal. Three in a row means something is wrong.
  4. Make endpoints idempotent — if a request gets retried, it shouldn’t create duplicate records or send duplicate emails.

Securing scheduled endpoints

If your scheduler is sending requests to your own API, you need to verify that the request is actually coming from your scheduler and not from an attacker:

  • Webhook signing — the scheduler includes a signature header (e.g., HMAC-SHA256) that you verify on the receiving end
  • API tokens — include a secret token in the Authorization header
  • IP allowlisting — restrict the endpoint to your scheduler’s IP range
  • Short-lived tokens — rotate credentials regularly

At minimum, use an API token in the Authorization header. Don’t leave scheduled endpoints open to the public internet.

Timezone handling

Cron expressions don’t include timezone information. If your scheduler runs in UTC (most do) and you need a job to fire at “9 AM New York time,” you have to account for daylight saving:

  • 9 AM EST (winter) = 0 14 * * * (UTC)
  • 9 AM EDT (summer) = 0 13 * * * (UTC)

Options

  1. Schedule in UTC and convert in your handler. Run the job hourly and check if it’s the right local time before executing. Simple but wasteful.
  2. Use a scheduler that supports timezones. Some schedulers let you specify a timezone alongside the cron expression. The scheduler handles DST transitions automatically.
  3. Adjust manually twice a year. Error-prone and easy to forget — not recommended for production.

For jobs where exact local time matters (sending a 9 AM email, triggering a billing run at midnight ET), use a scheduler with timezone support. For everything else, schedule in UTC and don’t worry about it.

Testing scheduled webhooks before going live

Don’t wait for the schedule to fire to find out your webhook is misconfigured. Before enabling a schedule:

  1. Test the endpoint manually — use curl or the webhook tester to send the exact request (method, headers, payload) your scheduler will send. Verify the endpoint returns 2xx.
Terminal window
curl -X POST https://api.example.com/sync \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"since": "1h"}' \
-w "\nHTTP Status: %{http_code}\nTime: %{time_total}s\n"
  1. Check authentication — if your endpoint requires a token, API key, or signature, make sure the scheduler has the right credentials. A 401 on the first automated run is the most common setup mistake.
  2. Verify timeout behavior — if your endpoint takes 20 seconds but the scheduler’s timeout is 10 seconds, every execution will fail. Time your endpoint and set the timeout with margin.
  3. Run a one-off trigger — most schedulers let you fire a job manually. Use this to see a real execution log before the schedule takes over.
  4. Check your logs — after the first scheduled execution, verify the request arrived at your endpoint with the expected headers and payload. Don’t assume — confirm.

Recuro: managed webhook scheduling

Recuro is a managed HTTP scheduler. Define your URL, method, headers, payload, and cron schedule — it handles execution, retries, and alerting:

  • Any HTTP method — GET, POST, PUT, PATCH, DELETE
  • Custom headers and payloads — set them once, change them anytime
  • Automatic retries with exponential backoff
  • Execution logs — status code, response time, and body for every run
  • Failure alerts — configurable consecutive failure thresholds
  • API access — create and manage schedules programmatically

Frequently asked questions

What's the difference between a cron job and a scheduled webhook?

A cron job is a general-purpose task scheduler — it runs any command on a timer. A scheduled webhook (or scheduled HTTP request) is a specific type of cron job that sends an HTTP request to a URL at each interval. You can implement a scheduled webhook using crontab with cURL, a framework scheduler, a cloud-native scheduler like AWS EventBridge, or a dedicated external HTTP scheduling service.

How do I schedule an HTTP request without a server?

Use a cloud-native scheduler or an external HTTP scheduling service. AWS EventBridge Scheduler, Google Cloud Scheduler, and Azure Logic Apps can all fire HTTP requests on a cron schedule without you managing a server. Alternatively, a dedicated service like Recuro lets you define the URL, method, headers, and schedule through a web UI or API — no infrastructure required.

Is webhook scheduling the same as event-driven webhooks?

No. Event-driven webhooks fire when something happens — a payment succeeds, a form is submitted, a deploy completes. The trigger is an event. Scheduled HTTP requests fire on a timer regardless of whether anything happened. They are time-driven, not event-driven. The term 'webhook scheduling' is sometimes used loosely, but the underlying mechanism is closer to a cron job that makes HTTP calls.

How do I monitor scheduled HTTP requests?

At minimum, log every execution with the HTTP status code, response time, and timestamp. Better solutions also track consecutive failures and send alerts when a threshold is exceeded, then send a recovery notification when the endpoint starts responding again. If you use crontab, you need to build this yourself. Framework schedulers, cloud schedulers, and external HTTP schedulers offer varying degrees of built-in monitoring.

What happens if my scheduled HTTP request fails?

That depends on your setup. Crontab with cURL does nothing — the request fails silently unless you added logging. Framework schedulers may log the error but typically do not retry. Cloud schedulers and external HTTP schedulers usually offer configurable retry policies with exponential backoff. Regardless of tool, make sure your receiving endpoint is idempotent so that retried requests do not cause duplicate side effects.

Can I schedule HTTP requests across different cloud providers?

Cloud-native schedulers like AWS EventBridge or Google Cloud Scheduler are designed for their own ecosystem. They can technically call any public URL, but managing schedules across multiple clouds means using multiple dashboards with no unified view. An external HTTP scheduler is cloud-agnostic — it calls any endpoint regardless of where it is hosted, and gives you a single dashboard for all your schedules.


Stop managing infrastructure. Start scheduling jobs.

Recuro handles cron scheduling, retries, alerts, and execution logs — so you can focus on building your product.

No credit card required