Skip to main content

JavaScript (Node.js)

This helper function polls GET /v1/webhook-events until a result for the given job_id appears or the timeout is reached.
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

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

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

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:
# 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