As of 2025-03-11, Grafana OnCall OSS has entered maintenance mode,
and will be archived on 2026-03-24. No further feature development will occur;
however, we will still provide fixes for critical bugs and for valid CVEs with a CVSS
score of 7.0 or higher. For more information, refer to our
blog post.
Important: This documentation is about an older version. It's relevant only to the release noted, many of the features and functions have been updated or replaced. Please view the current version.
Schedule type. May be ical (used for iCalendar integration) or calendar (used for manually created on-call shifts).
team_id
No
No
ID of the team.
time_zone
No
Optional
Schedule time zone. Is used for manually added on-call shifts in Schedules with type calendar. Default time zone is UTC. For more information about time zones, see
time zones.
ical_url_primary
No
If type = ical
URL of external iCal calendar for schedule with type ical.
ical_url_overrides
No
Optional
URL of external iCal calendar for schedule with any type. Events from this calendar override events from primary calendar or from on-call shifts.
slack
No
Optional
Dictionary with Slack-specific settings for a schedule. Includes channel_id and user_group_id fields, that take a channel ID and a user group ID from Slack.
shifts
No
Optional
List of shifts. Used for manually added on-call shifts in Schedules with type calendar.
HTTP request
POST {{API_URL}}/api/v1/schedules/
Get a schedule
shell
curl"{{API_URL}}/api/v1/schedules/SBM7DV7BKFUYU/"\--request GET \--header"Authorization: meowmeowmeow"\--header"Content-Type: application/json"\
The above command returns JSON structured in the following way:
curl"{{API_URL}}/api/v1/schedules/SBM7DV7BKFUYU/final_shifts?start_date=2023-01-01&end_date=2023-02-01"\--request GET \--header"Authorization: meowmeowmeow"
The above command returns JSON structured in the following way:
Some notes on the start_date and end_date query parameters:
they are both required and should represent ISO 8601 formatted dates
end_date must be greater than or equal to start_date
end_date cannot be more than 365 days in the future from start_date
Lastly, this endpoint is currently only active for web schedules. It will return HTTP 400 for schedules
defined via Terraform or iCal.
Example script to transform data to .csv for all of your schedules
The following Python script will generate a .csv file, oncall-report-2023-01-01-to-2023-01-31.csv. This file will
contain three columns, user_pk, user_email, and hours_on_call, which represents how many hours each user was
on call during the period starting January 1, 2023 to January 31, 2023 (inclusive).
python
import csv
import requests
from datetime import datetime
# CUSTOMIZE THE FOLLOWING VARIABLES
START_DATE ="2023-01-01"
END_DATE ="2023-01-31"
OUTPUT_FILE_NAME =f"oncall-report-{START_DATE}-to-{END_DATE}.csv"
MY_ONCALL_API_BASE_URL ="https://oncall-prod-us-central-0.grafana.net/oncall/api/v1/schedules"
MY_ONCALL_API_KEY ="meowmeowwoofwoof"
headers ={"Authorization": MY_ONCALL_API_KEY}
schedule_ids =[schedule["id"]for schedule in requests.get(MY_ONCALL_API_BASE_URL, headers=headers).json()["results"]]
user_on_call_hours ={}for schedule_id in schedule_ids:
response = requests.get(f"{MY_ONCALL_API_BASE_URL}/{schedule_id}/final_shifts?start_date={START_DATE}&end_date={END_DATE}",
headers=headers)for final_shift in response.json()["results"]:
user_pk = final_shift["user_pk"]
end = datetime.fromisoformat(final_shift["shift_end"])
start = datetime.fromisoformat(final_shift["shift_start"])
shift_time_in_seconds =(end - start).total_seconds()
shift_time_in_hours = shift_time_in_seconds /(60*60)if user_pk in user_on_call_hours:
user_on_call_hours[user_pk]["hours_on_call"]+= shift_time_in_hours
else:
user_on_call_hours[user_pk]={"email": final_shift["user_email"],"hours_on_call": shift_time_in_hours,}withopen(OUTPUT_FILE_NAME,"w")as fp:
csv_writer = csv.DictWriter(fp,["user_pk","user_email","hours_on_call"])
csv_writer.writeheader()for user_pk, user_info in user_on_call_hours.items():
csv_writer.writerow({"user_pk": user_pk,"user_email": user_info["email"],"hours_on_call": user_info["hours_on_call"]})