Schedule Endpoints
Create and manage automated, recurring scrapes via HTTP.
Create schedule
Create a new recurring schedule.
Request body (interval-based)
{
"strategy_id" : "550e8400-e29b-41d4-a716-446655440000" ,
"url" : "https://example.com/products" ,
"interval_seconds" : 3600 ,
"webhook_url" : "https://your-app.com/webhooks/meter"
}
Request body (cron-based)
{
"strategy_id" : "550e8400-e29b-41d4-a716-446655440000" ,
"url" : "https://example.com/products" ,
"cron_expression" : "0 9 * * *" ,
"webhook_url" : "https://your-app.com/webhooks/meter"
}
Field Type Required Description strategy_idstring Yes Strategy UUID urlstring Conditional Single URL to scrape (use url OR urls, not both) urlsarray Conditional List of URLs to scrape (use url OR urls, not both) interval_secondsinteger Conditional Interval in seconds (minimum: 60) cron_expressionstring Conditional Cron expression webhook_urlstring No Webhook URL for notifications webhook_metadataobject No Custom JSON metadata included in every webhook payload webhook_secretstring No Secret for X-Webhook-Secret header. Auto-generated if not provided when webhook_url is set webhook_typestring No standard or slack. Auto-detected from URL if not specifiedparametersobject No Default API parameter overrides for all scheduled runs (API strategies only)
Provide either interval_seconds or cron_expression, not both. Provide either url or urls, not both.
Response
{
"schedule_id" : "880e8400-e29b-41d4-a716-446655440000" ,
"strategy_id" : "550e8400-e29b-41d4-a716-446655440000" ,
"url" : "https://example.com/products" ,
"urls" : null ,
"schedule_type" : "interval" ,
"interval_seconds" : 3600 ,
"cron_expression" : null ,
"enabled" : true ,
"webhook_url" : "https://your-app.com/webhooks/meter" ,
"webhook_metadata" : null ,
"webhook_secret" : "whsec_a1b2c3..." ,
"webhook_type" : "standard" ,
"parameters" : null ,
"next_run_at" : "2025-01-15T11:30:00Z" ,
"last_run_at" : null ,
"created_at" : "2025-01-15T10:30:00Z" ,
"updated_at" : "2025-01-15T10:30:00Z"
}
The webhook_secret is only returned in the create response. It is not included in subsequent GET responses.
### Example
```bash
# Interval-based
curl -X POST https://api.meter.sh/api/schedules \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"strategy_id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://example.com/products",
"interval_seconds": 3600
}'
# Cron-based
curl -X POST https://api.meter.sh/api/schedules \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"strategy_id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://example.com/products",
"cron_expression": "0 9 * * *"
}'
List schedules
Get all schedules for the authenticated user.
Response
Array of schedule objects (same format as Create schedule response).
Example
curl https://api.meter.sh/api/schedules \
-H "Authorization: Bearer sk_live_..."
Update schedule
Update an existing schedule.
PATCH /api/schedules/{schedule_id}
Request body
All fields are optional. Include only fields to update:
{
"enabled" : false ,
"interval_seconds" : 7200 ,
"webhook_url" : "https://new-domain.com/webhooks" ,
"webhook_metadata" : { "project" : "updated-project" },
"webhook_type" : "standard"
}
Field Type Description enabledboolean Enable/disable the schedule urlstring Update to a single URL urlsarray Update to multiple URLs interval_secondsinteger New interval in seconds cron_expressionstring New cron expression webhook_urlstring New webhook URL (or null to remove) webhook_metadataobject Update custom JSON metadata for webhook payloads webhook_secretstring Update webhook secret webhook_typestring Update webhook type: standard or slack parametersobject Update API parameter defaults
Response
Updated schedule object.
Example
# Disable schedule
curl -X PATCH https://api.meter.sh/api/schedules/880e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"enabled": false}'
# Change interval
curl -X PATCH https://api.meter.sh/api/schedules/880e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"interval_seconds": 7200}'
Delete schedule
Delete a schedule (stops future jobs).
DELETE /api/schedules/{schedule_id}
Response
{
"message" : "Schedule deleted successfully"
}
Example
curl -X DELETE https://api.meter.sh/api/schedules/880e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer sk_live_..."
Regenerate webhook secret
Generate a new webhook secret for a schedule. The old secret is immediately invalidated.
POST /api/schedules/{schedule_id}/webhook-secret/regenerate
Response
{
"schedule_id" : "880e8400-e29b-41d4-a716-446655440000" ,
"webhook_secret" : "whsec_new_secret_here..."
}
The new secret is returned only once. Store it securely and update your webhook handler before the next delivery.
Example
curl -X POST https://api.meter.sh/api/schedules/880e8400-e29b-41d4-a716-446655440000/webhook-secret/regenerate \
-H "Authorization: Bearer sk_live_..."
Get schedule changes
Get unseen changes for a schedule (pull-based change detection).
GET /api/schedules/{schedule_id}/changes?mark_seen=true&filter=+keyword
Query parameters
Parameter Type Required Description mark_seenboolean No Mark changes as seen (default: true) filterstring No Lucene-style keyword filter for result items
Keyword filter syntax
The filter parameter uses Lucene-style syntax to filter individual result items:
Syntax Meaning Example +keywordRequired (AND) +rubio +tariff - items with bothkeywordOptional (OR) rubio elon - items with either-keywordExcluded (NOT) -bitcoin - items without"phrase"Exact phrase "elon musk" - exact match
The filter applies to individual items within results, not entire jobs.
Jobs with zero matching items are excluded from the response.
Response
{
"schedule_id" : "880e8400-e29b-41d4-a716-446655440000" ,
"changes" : [
{
"job_id" : "660e8400-e29b-41d4-a716-446655440000" ,
"status" : "completed" ,
"results" : [ ... ],
"item_count" : 12 ,
"content_hash" : "7f3d9a2b4c1e..." ,
"completed_at" : "2025-01-15T10:30:12Z" ,
"seen" : true
}
],
"count" : 1 ,
"marked_seen" : true ,
"filter_applied" : "+rubio +tariff"
}
Example
# Get and mark as seen
curl https://api.meter.sh/api/schedules/880e8400-e29b-41d4-a716-446655440000/changes \
-H "Authorization: Bearer sk_live_..."
# Preview without marking
curl https://api.meter.sh/api/schedules/880e8400-e29b-41d4-a716-446655440000/changes?mark_seen= false \
-H "Authorization: Bearer sk_live_..."
# Filter for items containing both "rubio" AND "tariff"
curl "https://api.meter.sh/api/schedules/880e8400-e29b-41d4-a716-446655440000/changes?filter=%2Brubio+%2Btariff" \
-H "Authorization: Bearer sk_live_..."
# Filter for items containing "rubio" OR "elon"
curl "https://api.meter.sh/api/schedules/880e8400-e29b-41d4-a716-446655440000/changes?filter=rubio+elon" \
-H "Authorization: Bearer sk_live_..."
# Filter for items with "rubio" but NOT "biden"
curl "https://api.meter.sh/api/schedules/880e8400-e29b-41d4-a716-446655440000/changes?filter=%2Brubio+-biden" \
-H "Authorization: Bearer sk_live_..."
Webhook payload
When a schedule has a webhook URL, Meter POSTs to it after each job:
{
"job_id" : "660e8400-e29b-41d4-a716-446655440000" ,
"schedule_id" : "880e8400-e29b-41d4-a716-446655440000" ,
"status" : "completed" ,
"results" : [ ... ],
"item_count" : 12 ,
"has_changes" : true ,
"content_hash" : "7f3d9a2b4c1e..." ,
"completed_at" : "2025-01-15T10:30:12Z"
}
See the Webhooks Guide for implementation details.
Error responses
Status Description 400Invalid request (invalid cron expression, missing required fields) 401Invalid or missing API key 404Schedule or strategy not found 500Internal server error 503Service temporarily unavailable
See REST API Errors for detailed error handling.
Next steps
Webhooks Guide Implement webhook endpoints
Pull-Based Monitoring Use the changes endpoint
Python SDK Use the Python SDK
Schedules Concept Learn about schedules
Need help?
Email me at mckinnon@meter.sh