> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meter.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Schedule Methods

> Automate scraping with recurring schedules

# Schedule Methods

Schedule methods allow you to set up automated, recurring scrapes. See the [MeterClient reference](/api-reference/python/client#schedule-methods) for complete method signatures.

## Quick reference

| Method                        | Description                              |
| ----------------------------- | ---------------------------------------- |
| `create_schedule()`           | Create a recurring schedule              |
| `list_schedules()`            | List all schedules                       |
| `update_schedule()`           | Modify schedule settings                 |
| `delete_schedule()`           | Delete a schedule                        |
| `get_schedule_changes()`      | Get unseen changes (pull-based)          |
| `regenerate_webhook_secret()` | Regenerate webhook secret for a schedule |

## Common workflows

### Interval-based monitoring

```python theme={null}
from meter_sdk import MeterClient

client = MeterClient(api_key="sk_live_...")

# Run every hour
schedule = client.create_schedule(
    strategy_id="550e8400-e29b-41d4-a716-446655440000",
    url="https://example.com/products",
    interval_seconds=3600
)

print(f"Schedule created: {schedule['schedule_id']}")
print(f"Next run: {schedule['next_run_at']}")
```

### Cron-based monitoring

```python theme={null}
# Daily at 9 AM
schedule = client.create_schedule(
    strategy_id="550e8400-e29b-41d4-a716-446655440000",
    url="https://example.com/products",
    cron_expression="0 9 * * *"
)

# Weekdays at 8 AM
schedule = client.create_schedule(
    strategy_id="550e8400-e29b-41d4-a716-446655440000",
    url="https://example.com/products",
    cron_expression="0 8 * * 1-5"
)
```

### With webhook

```python theme={null}
schedule = client.create_schedule(
    strategy_id="550e8400-e29b-41d4-a716-446655440000",
    url="https://example.com/products",
    interval_seconds=3600,
    webhook_url="https://your-app.com/webhooks/meter"
)

# Store the auto-generated webhook secret (shown only once)
print(f"Webhook secret: {schedule.get('webhook_secret')}")
```

### With webhook metadata and type

Attach custom metadata to every webhook payload and specify the delivery format:

```python theme={null}
# Standard webhook with metadata
schedule = client.create_schedule(
    strategy_id="550e8400-e29b-41d4-a716-446655440000",
    url="https://example.com/products",
    interval_seconds=3600,
    webhook_url="https://your-app.com/webhooks/meter",
    webhook_metadata={"project": "price-monitor", "env": "prod"},
    webhook_type="standard"
)

# Slack webhook (auto-detected from URL)
schedule = client.create_schedule(
    strategy_id="550e8400-e29b-41d4-a716-446655440000",
    url="https://example.com/products",
    interval_seconds=3600,
    webhook_url="https://hooks.slack.com/services/T.../B.../xxx"
)
```

### Regenerate webhook secret

If a webhook secret is compromised, regenerate it:

```python theme={null}
result = client.regenerate_webhook_secret(schedule_id)
new_secret = result["webhook_secret"]
# Update your webhook handler with the new secret
```

### With API parameters

For API-based strategies, set default parameters for all scheduled runs:

```python theme={null}
schedule = client.create_schedule(
    strategy_id="550e8400-e29b-41d4-a716-446655440000",
    url="https://example.com/api/listings",
    interval_seconds=3600,
    parameters={
        "category": "electronics",
        "sort": "newest",
        "limit": 100
    }
)

# Update parameters later
client.update_schedule(
    schedule['schedule_id'],
    parameters={"category": "clothing", "limit": 200}
)
```

### Multiple URLs

Monitor multiple pages on a single schedule:

```python theme={null}
schedule = client.create_schedule(
    strategy_id="550e8400-e29b-41d4-a716-446655440000",
    urls=[
        "https://example.com/products/electronics",
        "https://example.com/products/clothing",
        "https://example.com/products/home"
    ],
    interval_seconds=3600
)
```

### Pull-based change detection

```python theme={null}
import time

while True:
    # Check for changes every hour
    changes = client.get_schedule_changes(
        schedule_id="880e8400-e29b-41d4-a716-446655440000",
        mark_seen=True
    )

    if changes['count'] > 0:
        print(f"Processing {changes['count']} changes")
        for change in changes['changes']:
            # Process change['results']
            update_database(change['results'])

    time.sleep(3600)
```

### Keyword filtering

Filter results to only include items matching specific keywords:

```python theme={null}
# Filter for articles mentioning both "jfk" AND "tariff"
changes = client.get_schedule_changes(
    schedule_id="880e8400-e29b-41d4-a716-446655440000",
    filter="+jfk +tariff"
)

# Filter for articles mentioning "jfk" OR "elon"
changes = client.get_schedule_changes(
    schedule_id="880e8400-e29b-41d4-a716-446655440000",
    filter="jfk elon"
)

# Filter for articles with "jfk" but NOT "biden"
changes = client.get_schedule_changes(
    schedule_id="880e8400-e29b-41d4-a716-446655440000",
    filter="+jfk -biden"
)

# Exact phrase matching
changes = client.get_schedule_changes(
    schedule_id="880e8400-e29b-41d4-a716-446655440000",
    filter='"elon musk"'
)
```

<Note>
  The filter applies to individual items within results. Only matching items are returned.
  Jobs with zero matching items are excluded entirely.
</Note>

### Manage schedules

```python theme={null}
# List all schedules
schedules = client.list_schedules()

for schedule in schedules:
    print(f"{schedule['schedule_id']}: {schedule['enabled']}")

# Disable temporarily
client.update_schedule(schedule_id, enabled=False)

# Change interval
client.update_schedule(schedule_id, interval_seconds=7200)

# Delete
client.delete_schedule(schedule_id)
```

### Pause and resume

```python theme={null}
# Pause during maintenance
client.update_schedule(schedule_id, enabled=False)

# Do maintenance work
regenerate_strategy()

# Resume
client.update_schedule(schedule_id, enabled=True)
```

## See also

<CardGroup cols={2}>
  <Card title="Full Method Reference" icon="code" href="/api-reference/python/client#schedule-methods">
    Complete parameter and return type documentation
  </Card>

  <Card title="Schedules Concept" icon="clock" href="/concepts/schedules">
    Understand schedule types and timing
  </Card>

  <Card title="REST API" icon="brackets-curly" href="/api-reference/rest/schedules">
    Schedule endpoints in the REST API
  </Card>

  <Card title="Pull-Based Monitoring" icon="download" href="/guides/pull-based-monitoring">
    Guide to using get\_schedule\_changes()
  </Card>
</CardGroup>

## Need help?

Email me at [mckinnon@meter.sh](mailto:mckinnon@meter.sh)
