curl --request GET \
--url https://api.usecobalt.com/v1/availability \
--header 'access_token: <api-key>' \
--header 'client_id: <api-key>' \
--header 'client_secret: <api-key>'import requests
url = "https://api.usecobalt.com/v1/availability"
headers = {
"client_id": "<api-key>",
"client_secret": "<api-key>",
"access_token": "<api-key>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {client_id: '<api-key>', client_secret: '<api-key>', access_token: '<api-key>'}
};
fetch('https://api.usecobalt.com/v1/availability', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.usecobalt.com/v1/availability",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"access_token: <api-key>",
"client_id: <api-key>",
"client_secret: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.usecobalt.com/v1/availability"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("client_id", "<api-key>")
req.Header.Add("client_secret", "<api-key>")
req.Header.Add("access_token", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.usecobalt.com/v1/availability")
.header("client_id", "<api-key>")
.header("client_secret", "<api-key>")
.header("access_token", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.usecobalt.com/v1/availability")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["client_id"] = '<api-key>'
request["client_secret"] = '<api-key>'
request["access_token"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"availability": [
{
"day_of_week": 5,
"date": "2024-04-05",
"duration_string": "540m",
"range_start": "2024-04-05T08:00:00.000-07:00",
"range_end": "2024-04-05T17:00:00.000-07:00",
"provider_id": "<string>",
"visit_type": "New Patient",
"available_appointments": 3,
"max_visits": 5,
"facility_id": "1",
"facility_name": "Main St Clinic"
}
],
"timezone": "<string>",
"warnings": [
"<string>"
]
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}Get Availability
Returns open scheduling slots computed from synced provider hours and booked appointments over a date range.
curl --request GET \
--url https://api.usecobalt.com/v1/availability \
--header 'access_token: <api-key>' \
--header 'client_id: <api-key>' \
--header 'client_secret: <api-key>'import requests
url = "https://api.usecobalt.com/v1/availability"
headers = {
"client_id": "<api-key>",
"client_secret": "<api-key>",
"access_token": "<api-key>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {client_id: '<api-key>', client_secret: '<api-key>', access_token: '<api-key>'}
};
fetch('https://api.usecobalt.com/v1/availability', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.usecobalt.com/v1/availability",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"access_token: <api-key>",
"client_id: <api-key>",
"client_secret: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.usecobalt.com/v1/availability"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("client_id", "<api-key>")
req.Header.Add("client_secret", "<api-key>")
req.Header.Add("access_token", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.usecobalt.com/v1/availability")
.header("client_id", "<api-key>")
.header("client_secret", "<api-key>")
.header("access_token", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.usecobalt.com/v1/availability")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["client_id"] = '<api-key>'
request["client_secret"] = '<api-key>'
request["access_token"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"availability": [
{
"day_of_week": 5,
"date": "2024-04-05",
"duration_string": "540m",
"range_start": "2024-04-05T08:00:00.000-07:00",
"range_end": "2024-04-05T17:00:00.000-07:00",
"provider_id": "<string>",
"visit_type": "New Patient",
"available_appointments": 3,
"max_visits": 5,
"facility_id": "1",
"facility_name": "Main St Clinic"
}
],
"timezone": "<string>",
"warnings": [
"<string>"
]
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}active=true AND hide_in_availability=false will appear in availability results. If you’ve set a provider’s hide_in_availability to true, they won’t appear here even if their status is active.provider_ids and location_ids to narrow returned availability. Both parameters accept comma-separated EHR IDs, for example provider_ids=prov1,prov2 and location_ids=loc1,loc2. Location filtering is applied to generated availability windows using each slot’s facility_id; slots without a facility_id are excluded when location_ids is provided.Example Request
curl -X GET https://api.usecobalt.com/v1/availability \
-H 'Content-Type: application/json' \
-H 'client_id: ci_live_198908HJDKJSH98789OHKJL' \
-H 'client_secret: cs_live_9827hofdsklOYYHJLJh' \
-H 'access_token: 493JKLHIU98789hLKH9HHJH' \
-G \
--data-urlencode "start_date=2024-03-14T00:00:00-07:00" \
--data-urlencode "end_date=2024-04-14T23:59:59-07:00" \
--data-urlencode "calculation_method=slots" \
--data-urlencode "provider_ids=3498234,9834521" \
--data-urlencode "location_ids=1" \
--data-urlencode "cancelled_statuses=canc,rs,cancsms"
Example Response
{
"success": true,
"results": {
"availability": [
{
"day_of_week": 5,
"date": "2024-04-05",
"duration_string": "9h",
"range_start": "2024-04-05T08:00:00.000-07:00",
"range_end": "2024-04-05T17:00:00.000-07:00",
"provider_id": "3498234",
"facility_id": "1", // if available in the EHR
"facility_name": "Main St Clinic", // if available in the EHR
"visit_type": "New Patient" // only present when calculation_method=slots
}
]
},
"timezone": "America/Los_Angeles"
}
Enhanced Response with Detailed Slot Information
When usingcalculation_method=slots, if the EHR provides detailed slot information, the response may include additional fields for capacity management:
{
"success": true,
"availability": [
{
"day_of_week": 2,
"date": "2025-01-14",
"duration_string": "30 minutes",
"range_start": "2025-01-14T09:00:00.000-08:00",
"range_end": "2025-01-14T09:30:00.000-08:00",
"provider_id": "12345",
"visit_type": "New Patient Visit",
"available_appointments": 3,
"max_visits": 5,
"facility_id": "LOC-001",
"facility_name": "Main Office"
},
{
"day_of_week": 2,
"date": "2025-01-14",
"duration_string": "15 minutes",
"range_start": "2025-01-14T10:00:00.000-08:00",
"range_end": "2025-01-14T10:15:00.000-08:00",
"provider_id": "12345",
"visit_type": "Follow-up",
"available_appointments": 1,
"max_visits": 1,
"facility_id": "LOC-001",
"facility_name": "Main Office"
}
],
"timezone": "America/Los_Angeles"
}
visit_type: The specific appointment type that can be booked in this slotavailable_appointments: How many more appointments can still be scheduled in this slotmax_visits: The total capacity of this slot (useful for understanding how many are already booked)facility_id: Unique identifier for the facility/locationfacility_name: Name of the facility/location
Calculation Methods
Thecalculation_method parameter determines how availability is calculated:
- gaps (Default): Calculates availability based on free time between a provider’s working hours and existing appointments
- slots: Pre-defined appointment slots blocked only by appointments matching the slot’s visit type
- equal_slots: Pre-defined appointment slots blocked by ANY appointment at that time, regardless of type
Example Scenarios
Scenario 1: A “New Patient” schedule_slot exists at 10:00 AM. A “Follow-up” appointment is already booked at 10:00 AM.- gaps: 10:00 AM not returned as available (appointment occupies that time)
- slots: “New Patient” slot returned as available (different appointment type doesn’t block)
- equal_slots: “New Patient” slot not returned (any appointment blocks all slot types)
- gaps: 10:00 AM not returned as available (appointment occupies that time)
- slots: “New Patient” slot not returned (same appointment type blocks)
- equal_slots: “New Patient” slot not returned (any appointment blocks all slot types)
- gaps: 10:00 AM not returned as available (schedule_block occupies that time)
- slots: “New Patient” slot not returned (schedule_blocks block slots)
- equal_slots: “New Patient” slot not returned (schedule_blocks block all slot types)
equal_slots when multiple parties (e.g., clinic staff and automated systems) are scheduling different appointment types into the same time slots and you need to prevent double-booking.Authorizations
Query Parameters
Range start (ISO 8601 / YYYY-MM-DD).
"2026-03-15"
Range end (ISO 8601 / YYYY-MM-DD). Must be on/after start_date and within 12 months.
"2026-03-20"
Comma-separated EMR provider IDs to filter by.
"PROV-1,PROV-2"
Comma-separated EMR location IDs to filter slots by.
"LOC-1,LOC-2"
Minutes of buffer between slots (0–59).
x >= 015
Visit-type code to size slots for. Requires buffer.
"FOLLOW-UP"
Slot calculation method.
gaps, slots, equal_slots Max appointments per day. Requires daily_limit_type.
x >= 18
Visit-type code the daily limit applies to. Requires daily_appointment_limit.
"all"
Which provider slot to match on.
primary, secondary Use default business hours when a provider has no configured hours.
true, false Cap on slot length in minutes (5–60, multiples of 5).
30
Scope slots per facility rather than per provider (auto-enabled for Practice Fusion).
true, false Comma-separated appointment statuses to treat as cancelled, freeing the slot. When provided, this overrides the default cancelled/rescheduled detection; statuses are matched case-insensitively. Use this when your clinic uses custom status codes (e.g. "RS" for rescheduled).
"canc,rs,cancsms"