Skip to content

Scheduling a Report

A saved report can run on a schedule. Each run requests the saved URL exactly as you would, so the URL decides what happens to the report.

To receive each run, save the URL with &delivery=email&[email protected]. Every run then arrives by email, and so does any error. A report without delivery=email is still generated on schedule, but nothing is sent anywhere.

Creating a Schedule

PUT the schedule onto a saved report, authenticated with your secret key:

# /// script
# requires-python = ">=3.8"
# dependencies = [
#     "httpx",
# ]
# ///
import httpx

SECRET_KEY = "YOUR_SECRET_KEY"
PUBLIC_ID = "YOUR_SAVED_REPORT_PUBLIC_ID"

response = httpx.put(
    f"https://api.trackandtrace.tools/v2/saved-reports/{PUBLIC_ID}/schedule",
    headers={"X-T3-API-Key": SECRET_KEY},
    json={
        "frequency": "daily",
        "timeOfDay": "06:00",
        "timezone": "America/Denver",
    },
)

print(response.json()["data"]["nextRunAt"])
frequency Runs
hourly Once an hour, at the same minute past every hour
daily Every day at timeOfDay in timezone, following daylight saving time
every5Minutes, every15Minutes, every30Minutes Every 5, 15 or 30 minutes. Only if your subscription allows it

timeOfDay and timezone go with daily only. timezone is an IANA name such as America/Denver or America/New_York.

A saved report has one schedule. Sending the PUT again replaces it.

Which Key Runs It

The schedule runs with the secret key you send the PUT with. A request authenticated with a bearer token is refused, because it leaves no key to run with.

  • Rotating that key keeps the schedule working.
  • Deleting it pauses the schedule.
  • To switch keys, send the PUT again with the other key.

The key is never returned. secretKeyHint shows its last four characters so you can tell which key it is.

Checking on It

schedule = httpx.get(
    f"https://api.trackandtrace.tools/v2/saved-reports/{PUBLIC_ID}/schedule",
    headers={"X-T3-API-Key": SECRET_KEY},
).json()["data"]

runs = httpx.get(
    f"https://api.trackandtrace.tools/v2/saved-reports/{PUBLIC_ID}/schedule/runs",
    headers={"X-T3-API-Key": SECRET_KEY},
).json()["data"]

for run in runs:
    print(run["createdAt"], run["status"], run["error"])
Run status Means
queued Accepted for delivery. The report, or an explanation of why it failed, arrives by email
succeeded The report was generated
failed It did not run; error says why
rate_limited Your report rate limit was reached. The next scheduled run tries again

Runs are kept for 30 days.

When a Schedule Pauses

A paused schedule has a pausedReason and does not run. To resume it, fix the cause and send the PUT again.

pausedReason Cause
credential_failure Metrc rejected the key's credentials, usually because the Metrc password changed. The schedule stops at once so repeated failed logins cannot lock your Metrc account. Generate a new key and PUT with it
secret_key_unavailable The key was deleted or disabled
limit_exceeded Your subscription no longer allows this schedule
consecutive_failures The report failed 5 runs in a row

Good to Know

  • Runs count toward your report rate limits, exactly like requests you make yourself.
  • Runs can start up to two minutes late, and missed runs are not caught up. A schedule that could not run for a while runs once, then carries on.
  • Prefer csv or xlsx. contentType=googleSheets creates a new sheet on every run.
  • Subscriptions allow 10 active schedules, and no more often than hourly, unless arranged otherwise.
  • Deleting the saved report deletes its schedule.
Method Path What it does
PUT /v2/saved-reports/{publicId}/schedule Create or replace the schedule, resuming it if paused
GET /v2/saved-reports/{publicId}/schedule Retrieve it
GET /v2/saved-reports/{publicId}/schedule/runs List its runs, newest first
DELETE /v2/saved-reports/{publicId}/schedule Stop it and delete its run history

Next Steps