JavaScript (Node.js)
This helper function pollsGET /v1/webhook-events until a result for the given job_id appears or the timeout is reached.
Copy
const axios = require('axios');
const COBALT_BASE_URL = 'https://api.usecobalt.com';
const headers = {
'Content-Type': 'application/json',
'client_id': process.env.COBALT_CLIENT_ID,
'client_secret': process.env.COBALT_CLIENT_SECRET,
'access_token': process.env.COBALT_ACCESS_TOKEN,
};
/**
* Poll for the result of an asynchronous Cobalt operation.
* @param {string} jobId - The job_id returned from the initial API call.
* @param {object} options
* @param {number} options.timeoutMs - Max time to wait (default: 120000ms / 2 minutes).
* @param {number} options.pollIntervalMs - Time between polls (default: 1000ms).
* @returns {object} The webhook event object with the operation result.
* @throws {Error} If the timeout is reached before a result is available.
*/
async function awaitResult(jobId, { timeoutMs = 120000, pollIntervalMs = 1000 } = {}) {
const startTime = Date.now();
while (Date.now() - startTime < timeoutMs) {
const response = await axios.get(`${COBALT_BASE_URL}/v1/webhook-events`, {
headers,
params: { job_id: jobId },
});
const events = response.data.webhook_events;
if (events && events.length > 0) {
return events[0];
}
await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
}
throw new Error(`Timed out after ${timeoutMs}ms waiting for result (job_id: ${jobId})`);
}
Creating an Appointment and Awaiting the Result
Copy
async function createAppointmentSync(appointmentData) {
// Step 1: Create the appointment
const createResponse = await axios.post(
`${COBALT_BASE_URL}/v1/appointments`,
appointmentData,
{ headers }
);
const { appointment_id, job_id } = createResponse.data.data;
console.log(`Appointment queued: ${appointment_id}, polling for result...`);
// Step 2: Wait for the outcome
const event = await awaitResult(job_id);
// Step 3: Handle the result
if (event.event_type === 'appointment.created') {
console.log('Appointment created successfully:', event.data);
return { success: true, data: event.data };
} else {
console.error('Appointment failed:', event.data.failure_reason);
return { success: false, error: event.data.failure_reason };
}
}
// Usage
const result = await createAppointmentSync({
mrn: '123456789',
location: '123456789',
datetime: '2025-03-15T14:00:00-05:00',
provider: '123456789',
type: 'follow_up',
});
Creating a Patient and Awaiting the Result
Copy
async function createPatientSync(patientData) {
const createResponse = await axios.post(
`${COBALT_BASE_URL}/v1/patients`,
patientData,
{ headers }
);
const { patient_id, job_id } = createResponse.data.data;
console.log(`Patient queued: ${patient_id}, polling for result...`);
const event = await awaitResult(job_id);
if (event.event_type === 'patient.created') {
console.log('Patient created successfully:', event.data);
return { success: true, data: event.data };
} else {
console.error('Patient creation failed:', event.data.failure_reason);
return { success: false, error: event.data.failure_reason };
}
}
Python
Copy
import requests
import time
COBALT_BASE_URL = "https://api.usecobalt.com"
headers = {
"Content-Type": "application/json",
"client_id": COBALT_CLIENT_ID,
"client_secret": COBALT_CLIENT_SECRET,
"access_token": COBALT_ACCESS_TOKEN,
}
def await_result(job_id, timeout_seconds=120, poll_interval_seconds=1):
"""
Poll for the result of an asynchronous Cobalt operation.
Args:
job_id: The job_id returned from the initial API call.
timeout_seconds: Max time to wait (default: 120 seconds).
poll_interval_seconds: Time between polls (default: 1 second).
Returns:
The webhook event dict with the operation result.
Raises:
TimeoutError: If the timeout is reached before a result is available.
"""
start_time = time.time()
while time.time() - start_time < timeout_seconds:
response = requests.get(
f"{COBALT_BASE_URL}/v1/webhook-events",
headers=headers,
params={"job_id": job_id},
)
response.raise_for_status()
events = response.json().get("webhook_events", [])
if events:
return events[0]
time.sleep(poll_interval_seconds)
raise TimeoutError(
f"Timed out after {timeout_seconds}s waiting for result (job_id: {job_id})"
)
def create_appointment_sync(appointment_data):
# Step 1: Create the appointment
create_response = requests.post(
f"{COBALT_BASE_URL}/v1/appointments",
headers=headers,
json=appointment_data,
)
create_response.raise_for_status()
data = create_response.json()["data"]
appointment_id = data["appointment_id"]
job_id = data["job_id"]
print(f"Appointment queued: {appointment_id}, polling for result...")
# Step 2: Wait for the outcome
event = await_result(job_id)
# Step 3: Handle the result
if event["event_type"] == "appointment.created":
print("Appointment created successfully:", event["data"])
return {"success": True, "data": event["data"]}
else:
print("Appointment failed:", event["data"]["failure_reason"])
return {"success": False, "error": event["data"]["failure_reason"]}
cURL
You can also poll manually with cURL for testing or debugging:Copy
# Step 1: Create the appointment
curl -X POST https://api.usecobalt.com/v1/appointments \
-H 'Content-Type: application/json' \
-H 'client_id: your_client_id' \
-H 'client_secret: your_client_secret' \
-H 'access_token: your_access_token' \
-d '{
"mrn": "123456789",
"location": "123456789",
"datetime": "2025-03-15T14:00:00-05:00",
"provider": "123456789",
"type": "follow_up"
}'
# Response: { "success": true, "data": { "appointment_id": "abc123", "job_id": "67890" } }
# Step 2: Poll for the result using the job_id
curl -X GET "https://api.usecobalt.com/v1/webhook-events?job_id=67890" \
-H 'client_id: your_client_id' \
-H 'client_secret: your_client_secret' \
-H 'access_token: your_access_token'
# Repeat until webhook_events array is non-empty
