curl --request POST \
--url https://api.usecobalt.com/v1/encounters \
--header 'Content-Type: application/json' \
--header 'access_token: <api-key>' \
--header 'client_id: <api-key>' \
--header 'client_secret: <api-key>' \
--data '
{
"patient_mrn": "15539",
"episode_id": "32340",
"encounter_type": "GAD-7",
"form_id": "392",
"answers": {
"427919": {
"value": "Other",
"notes": "School visit"
},
"427920": "Narrative text for the contact.",
"467752": "2026-09-24",
"467761": "Therapy",
"467762": "Reason for the referral.",
"467767": [
"Mornings",
"Afternoons"
]
},
"encounter_date": "2026-08-26",
"callback_urls": [
"<string>"
]
}
'import requests
url = "https://api.usecobalt.com/v1/encounters"
payload = {
"patient_mrn": "15539",
"episode_id": "32340",
"encounter_type": "GAD-7",
"form_id": "392",
"answers": {
"427919": {
"value": "Other",
"notes": "School visit"
},
"427920": "Narrative text for the contact.",
"467752": "2026-09-24",
"467761": "Therapy",
"467762": "Reason for the referral.",
"467767": ["Mornings", "Afternoons"]
},
"encounter_date": "2026-08-26",
"callback_urls": ["<string>"]
}
headers = {
"client_id": "<api-key>",
"client_secret": "<api-key>",
"access_token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
client_id: '<api-key>',
client_secret: '<api-key>',
access_token: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
patient_mrn: '15539',
episode_id: '32340',
encounter_type: 'GAD-7',
form_id: '392',
answers: {
'427919': {value: 'Other', notes: 'School visit'},
'427920': 'Narrative text for the contact.',
'467752': '2026-09-24',
'467761': 'Therapy',
'467762': 'Reason for the referral.',
'467767': ['Mornings', 'Afternoons']
},
encounter_date: '2026-08-26',
callback_urls: ['<string>']
})
};
fetch('https://api.usecobalt.com/v1/encounters', 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/encounters",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'patient_mrn' => '15539',
'episode_id' => '32340',
'encounter_type' => 'GAD-7',
'form_id' => '392',
'answers' => [
'427919' => [
'value' => 'Other',
'notes' => 'School visit'
],
'427920' => 'Narrative text for the contact.',
'467752' => '2026-09-24',
'467761' => 'Therapy',
'467762' => 'Reason for the referral.',
'467767' => [
'Mornings',
'Afternoons'
]
],
'encounter_date' => '2026-08-26',
'callback_urls' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.usecobalt.com/v1/encounters"
payload := strings.NewReader("{\n \"patient_mrn\": \"15539\",\n \"episode_id\": \"32340\",\n \"encounter_type\": \"GAD-7\",\n \"form_id\": \"392\",\n \"answers\": {\n \"427919\": {\n \"value\": \"Other\",\n \"notes\": \"School visit\"\n },\n \"427920\": \"Narrative text for the contact.\",\n \"467752\": \"2026-09-24\",\n \"467761\": \"Therapy\",\n \"467762\": \"Reason for the referral.\",\n \"467767\": [\n \"Mornings\",\n \"Afternoons\"\n ]\n },\n \"encounter_date\": \"2026-08-26\",\n \"callback_urls\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("client_id", "<api-key>")
req.Header.Add("client_secret", "<api-key>")
req.Header.Add("access_token", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.usecobalt.com/v1/encounters")
.header("client_id", "<api-key>")
.header("client_secret", "<api-key>")
.header("access_token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"patient_mrn\": \"15539\",\n \"episode_id\": \"32340\",\n \"encounter_type\": \"GAD-7\",\n \"form_id\": \"392\",\n \"answers\": {\n \"427919\": {\n \"value\": \"Other\",\n \"notes\": \"School visit\"\n },\n \"427920\": \"Narrative text for the contact.\",\n \"467752\": \"2026-09-24\",\n \"467761\": \"Therapy\",\n \"467762\": \"Reason for the referral.\",\n \"467767\": [\n \"Mornings\",\n \"Afternoons\"\n ]\n },\n \"encounter_date\": \"2026-08-26\",\n \"callback_urls\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.usecobalt.com/v1/encounters")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["client_id"] = '<api-key>'
request["client_secret"] = '<api-key>'
request["access_token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"patient_mrn\": \"15539\",\n \"episode_id\": \"32340\",\n \"encounter_type\": \"GAD-7\",\n \"form_id\": \"392\",\n \"answers\": {\n \"427919\": {\n \"value\": \"Other\",\n \"notes\": \"School visit\"\n },\n \"427920\": \"Narrative text for the contact.\",\n \"467752\": \"2026-09-24\",\n \"467761\": \"Therapy\",\n \"467762\": \"Reason for the referral.\",\n \"467767\": [\n \"Mornings\",\n \"Afternoons\"\n ]\n },\n \"encounter_date\": \"2026-08-26\",\n \"callback_urls\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"encounter_id": "<string>",
"job_id": 123
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}Create Encounter
Queues an encounter (an episode visit with form documentation) for creation in the provider’s EMR system.
curl --request POST \
--url https://api.usecobalt.com/v1/encounters \
--header 'Content-Type: application/json' \
--header 'access_token: <api-key>' \
--header 'client_id: <api-key>' \
--header 'client_secret: <api-key>' \
--data '
{
"patient_mrn": "15539",
"episode_id": "32340",
"encounter_type": "GAD-7",
"form_id": "392",
"answers": {
"427919": {
"value": "Other",
"notes": "School visit"
},
"427920": "Narrative text for the contact.",
"467752": "2026-09-24",
"467761": "Therapy",
"467762": "Reason for the referral.",
"467767": [
"Mornings",
"Afternoons"
]
},
"encounter_date": "2026-08-26",
"callback_urls": [
"<string>"
]
}
'import requests
url = "https://api.usecobalt.com/v1/encounters"
payload = {
"patient_mrn": "15539",
"episode_id": "32340",
"encounter_type": "GAD-7",
"form_id": "392",
"answers": {
"427919": {
"value": "Other",
"notes": "School visit"
},
"427920": "Narrative text for the contact.",
"467752": "2026-09-24",
"467761": "Therapy",
"467762": "Reason for the referral.",
"467767": ["Mornings", "Afternoons"]
},
"encounter_date": "2026-08-26",
"callback_urls": ["<string>"]
}
headers = {
"client_id": "<api-key>",
"client_secret": "<api-key>",
"access_token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
client_id: '<api-key>',
client_secret: '<api-key>',
access_token: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
patient_mrn: '15539',
episode_id: '32340',
encounter_type: 'GAD-7',
form_id: '392',
answers: {
'427919': {value: 'Other', notes: 'School visit'},
'427920': 'Narrative text for the contact.',
'467752': '2026-09-24',
'467761': 'Therapy',
'467762': 'Reason for the referral.',
'467767': ['Mornings', 'Afternoons']
},
encounter_date: '2026-08-26',
callback_urls: ['<string>']
})
};
fetch('https://api.usecobalt.com/v1/encounters', 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/encounters",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'patient_mrn' => '15539',
'episode_id' => '32340',
'encounter_type' => 'GAD-7',
'form_id' => '392',
'answers' => [
'427919' => [
'value' => 'Other',
'notes' => 'School visit'
],
'427920' => 'Narrative text for the contact.',
'467752' => '2026-09-24',
'467761' => 'Therapy',
'467762' => 'Reason for the referral.',
'467767' => [
'Mornings',
'Afternoons'
]
],
'encounter_date' => '2026-08-26',
'callback_urls' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.usecobalt.com/v1/encounters"
payload := strings.NewReader("{\n \"patient_mrn\": \"15539\",\n \"episode_id\": \"32340\",\n \"encounter_type\": \"GAD-7\",\n \"form_id\": \"392\",\n \"answers\": {\n \"427919\": {\n \"value\": \"Other\",\n \"notes\": \"School visit\"\n },\n \"427920\": \"Narrative text for the contact.\",\n \"467752\": \"2026-09-24\",\n \"467761\": \"Therapy\",\n \"467762\": \"Reason for the referral.\",\n \"467767\": [\n \"Mornings\",\n \"Afternoons\"\n ]\n },\n \"encounter_date\": \"2026-08-26\",\n \"callback_urls\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("client_id", "<api-key>")
req.Header.Add("client_secret", "<api-key>")
req.Header.Add("access_token", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.usecobalt.com/v1/encounters")
.header("client_id", "<api-key>")
.header("client_secret", "<api-key>")
.header("access_token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"patient_mrn\": \"15539\",\n \"episode_id\": \"32340\",\n \"encounter_type\": \"GAD-7\",\n \"form_id\": \"392\",\n \"answers\": {\n \"427919\": {\n \"value\": \"Other\",\n \"notes\": \"School visit\"\n },\n \"427920\": \"Narrative text for the contact.\",\n \"467752\": \"2026-09-24\",\n \"467761\": \"Therapy\",\n \"467762\": \"Reason for the referral.\",\n \"467767\": [\n \"Mornings\",\n \"Afternoons\"\n ]\n },\n \"encounter_date\": \"2026-08-26\",\n \"callback_urls\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.usecobalt.com/v1/encounters")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["client_id"] = '<api-key>'
request["client_secret"] = '<api-key>'
request["access_token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"patient_mrn\": \"15539\",\n \"episode_id\": \"32340\",\n \"encounter_type\": \"GAD-7\",\n \"form_id\": \"392\",\n \"answers\": {\n \"427919\": {\n \"value\": \"Other\",\n \"notes\": \"School visit\"\n },\n \"427920\": \"Narrative text for the contact.\",\n \"467752\": \"2026-09-24\",\n \"467761\": \"Therapy\",\n \"467762\": \"Reason for the referral.\",\n \"467767\": [\n \"Mornings\",\n \"Afternoons\"\n ]\n },\n \"encounter_date\": \"2026-08-26\",\n \"callback_urls\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"encounter_id": "<string>",
"job_id": 123
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}/encounters call you can display a Processing status to your user, and when you receive the webhook notification you can update that to Completed.
How an encounter is created
Processing an encounter runs an ordered chain against the EMR:- Episode — the encounter is attached to the episode you give in
episode_id. There is no fallback to another episode. Assign the patient to a team first, as a separate step, to open the episode. - Encounter type — the
encounter_typeis resolved against the client’s live billing matrix. An encounter type that is not billable for the client fails the encounter (see Failure). - Form documentation — the
answersyou supply are validated against the synced form definition (form_id) and written on the encounter. For a scored questionnaire, per-question scores are entered and totals and risk bands are derived by the EMR. - Read-back — after signing, the encounter is re-read from the EMR to confirm it persisted before the success webhook is sent.
Request Parameters
Required Fields
- patient_mrn (string, required): The patient’s medical record number. The patient must already be synced to Cobalt.
- episode_id (string, required): The episode the encounter is created under. Use the exact id from the patient episode payload.
- encounter_type (string, required): The encounter type to add, by name or numeric visit-type id (for example
"GAD-7"). Must be billable for the client — that is, present in the client’s billing matrix. - form_id (string, required): EMR form id whose answers you are providing — the
emr_form_idof a form fromGET /v1/forms. Required when the encounter type documents a form. - answers (object, required): Form answers keyed by EMR question id (the
emrQuestionIdof each question in the form definition — seeGET /v1/forms/{id}). For a scored questionnaire, provide the numeric score for each scored question; totals and risk bands are derived automatically. Answers are validated against the synced form definition before the encounter is written.
Optional Fields
- encounter_date (string, optional): Encounter date in
YYYY-MM-DDformat. Defaults to today. Cannot be in the future. - callback_urls (array of strings, optional): URLs to receive the completion webhook for this encounter, in addition to your account webhook.
Example Request
curl -X POST https://api.usecobalt.com/v1/encounters \
-H 'Content-Type: application/json' \
-H 'client_id: ci_live_198908HJDKJSH98789OHKJL' \
-H 'client_secret: cs_live_9827hofdsklOYYHJLJh' \
-H 'access_token: 493JKLHIU98789hLKH9HHJH' \
-d '{
"patient_mrn": "1234567",
"episode_id": "32340",
"encounter_type": "GAD-7",
"form_id": "392",
"encounter_date": "2026-08-26",
"answers": {
"453149": "3",
"453150": "2",
"453156": "Very difficult"
}
}'
Example Response
{
"success": true,
"message": "Encounter processing. A webhook event will be sent upon completion.",
"encounter_id": "123e4567e89b12d3a456426614174000",
"job_id": 12345
}
- encounter_id: Cobalt encounter ID (UUID without dashes). This is echoed back in the webhook payload so you can correlate the two.
- job_id: Job execution identifier for tracking the async operation.
Error Responses
Missing Required Field
{
"success": false,
"message": "Missing required field: patient_mrn"
}
Answers Not An Object
{
"success": false,
"message": "answers must be an object keyed by EMR question id."
}
Invalid Encounter Date
{
"success": false,
"message": "encounter_date must be a valid date (YYYY-MM-DD)."
}
{
"success": false,
"message": "encounter_date cannot be in the future."
}
User Not Found
{
"success": false,
"message": "User not found."
}
Unsupported EMR
{
"success": false,
"message": "Creating encounters is not supported for [EMR Name]."
}
Webhook Notifications
When the encounter has finished processing, we send a webhook to your registered endpoint.Success
{
"id": "<id-of-webhook-response>",
"access_token_reference_id": "<access-token-reference-id>",
"object": "event",
"created": "2026-08-26T10:30:00.000Z",
"type": "encounter.created",
"data": {
"encounter_id": "123e4567e89b12d3a456426614174000",
"emr_encounter_id": "927341",
"emr_episode_id": "88214",
"patient_mrn": "1234567"
}
}
- encounter_id: The Cobalt encounter ID you received in the response.
- emr_encounter_id: The encounter id in the EMR.
- emr_episode_id: The episode the encounter was written under.
- patient_mrn: The patient’s medical record number.
Failure
{
"id": "<id-of-webhook-response>",
"access_token_reference_id": "<access-token-reference-id>",
"object": "event",
"created": "2026-08-26T10:35:00.000Z",
"type": "encounter.failed",
"data": {
"encounter_id": "123e4567e89b12d3a456426614174000",
"emr_encounter_id": null,
"patient_mrn": "1234567",
"failure_reason": "Encounter type 'GAD-7' not available for client 1234567 (not in billing matrix)"
}
}
encounter.failed event is sent once, when the failure is permanent. Common failure_reason values:
Encounter type '<type>' not available for client <mrn> (not in billing matrix)— the encounter type is not billable for the client.Missing required answers: <question ids>— one or more required form questions were not answered.
Authorizations
Body
Medical Record Number (Credible client id) of the patient.
"15539"
Episode (FHIR EpisodeOfCare) the encounter is created under. Pull the exact id from the patient episode payload and pass it here — the encounter attaches to this episode with no fallback. Assign the patient to a team first (a separate step) to open the episode.
"32340"
Encounter type to add, by name or numeric visit-type id (e.g. "GAD-7").
"GAD-7"
EMR form id whose answers are provided (from GET /v1/forms). Required when the encounter type documents a form.
"392"
Form answers keyed by EMR question id (from GET /v1/forms). Value by question format: single choice (radio, push button) and dropdown take the answer value or answer id; check box (multi-select) takes a list of answer values or ids; text box takes a string; date takes YYYY-MM-DD. An open-text narrative question takes the text as a string. To add notes to a choice (e.g. "Other"), send { "value": "Other", "notes": "..." }. For a scored questionnaire (e.g. GAD-7) provide the numeric score for each scored question; totals and risk bands are derived automatically. A conditional question (shown only after a trigger answer) is accepted only when its trigger answer is also supplied. An answer that does not match the form fails the request.
Show child attributes
Show child attributes
{
"427919": { "value": "Other", "notes": "School visit" },
"427920": "Narrative text for the contact.",
"467752": "2026-09-24",
"467761": "Therapy",
"467762": "Reason for the referral.",
"467767": ["Mornings", "Afternoons"]
}
Encounter date (YYYY-MM-DD). Defaults to today. Cannot be in the future.
"2026-08-26"
URLs to receive the completion webhook for this encounter, in addition to the account webhook.