curl --request POST \
--url https://api.doozy.live/v1/tracks/{trackId}/enroll \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"email": "user@example.com",
"user_id": "abc123",
"slack_user_id": "U01ABC2DEF3",
"allow_already_completed": false,
"start_at": "2026-02-20T09:00:00.000Z",
"catch_up": true,
"run_every_day": false
}
'import requests
url = "https://api.doozy.live/v1/tracks/{trackId}/enroll"
payload = {
"email": "user@example.com",
"user_id": "abc123",
"slack_user_id": "U01ABC2DEF3",
"allow_already_completed": False,
"start_at": "2026-02-20T09:00:00.000Z",
"catch_up": True,
"run_every_day": False
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
email: 'user@example.com',
user_id: 'abc123',
slack_user_id: 'U01ABC2DEF3',
allow_already_completed: false,
start_at: '2026-02-20T09:00:00.000Z',
catch_up: true,
run_every_day: false
})
};
fetch('https://api.doozy.live/v1/tracks/{trackId}/enroll', 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.doozy.live/v1/tracks/{trackId}/enroll",
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([
'email' => 'user@example.com',
'user_id' => 'abc123',
'slack_user_id' => 'U01ABC2DEF3',
'allow_already_completed' => false,
'start_at' => '2026-02-20T09:00:00.000Z',
'catch_up' => true,
'run_every_day' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <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.doozy.live/v1/tracks/{trackId}/enroll"
payload := strings.NewReader("{\n \"email\": \"user@example.com\",\n \"user_id\": \"abc123\",\n \"slack_user_id\": \"U01ABC2DEF3\",\n \"allow_already_completed\": false,\n \"start_at\": \"2026-02-20T09:00:00.000Z\",\n \"catch_up\": true,\n \"run_every_day\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<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.doozy.live/v1/tracks/{trackId}/enroll")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"user@example.com\",\n \"user_id\": \"abc123\",\n \"slack_user_id\": \"U01ABC2DEF3\",\n \"allow_already_completed\": false,\n \"start_at\": \"2026-02-20T09:00:00.000Z\",\n \"catch_up\": true,\n \"run_every_day\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.doozy.live/v1/tracks/{trackId}/enroll")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email\": \"user@example.com\",\n \"user_id\": \"abc123\",\n \"slack_user_id\": \"U01ABC2DEF3\",\n \"allow_already_completed\": false,\n \"start_at\": \"2026-02-20T09:00:00.000Z\",\n \"catch_up\": true,\n \"run_every_day\": false\n}"
response = http.request(request)
puts response.read_body{
"object": "track_enrollment",
"track_id": "wf_abc123xyz",
"user_id": "usr_abc123",
"instance_id": "inst_xyz789",
"status": "active",
"enrolled_at": "2026-02-18T10:30:00.000Z",
"starts_at": "2026-02-20T09:00:00.000Z"
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "No such quiz: quiz_abc123",
"param": "id",
"doc_url": "https://docs.doozy.live/api/errors#resource_not_found"
}
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "No such quiz: quiz_abc123",
"param": "id",
"doc_url": "https://docs.doozy.live/api/errors#resource_not_found"
}
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "No such quiz: quiz_abc123",
"param": "id",
"doc_url": "https://docs.doozy.live/api/errors#resource_not_found"
}
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "No such quiz: quiz_abc123",
"param": "id",
"doc_url": "https://docs.doozy.live/api/errors#resource_not_found"
}
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "No such quiz: quiz_abc123",
"param": "id",
"doc_url": "https://docs.doozy.live/api/errors#resource_not_found"
}
}Enroll user in track
Enroll a user in a track. The user must be connected to Slack and have at least one role assigned. Exactly one of email, user_id, or slack_user_id must be provided to identify the user.
curl --request POST \
--url https://api.doozy.live/v1/tracks/{trackId}/enroll \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"email": "user@example.com",
"user_id": "abc123",
"slack_user_id": "U01ABC2DEF3",
"allow_already_completed": false,
"start_at": "2026-02-20T09:00:00.000Z",
"catch_up": true,
"run_every_day": false
}
'import requests
url = "https://api.doozy.live/v1/tracks/{trackId}/enroll"
payload = {
"email": "user@example.com",
"user_id": "abc123",
"slack_user_id": "U01ABC2DEF3",
"allow_already_completed": False,
"start_at": "2026-02-20T09:00:00.000Z",
"catch_up": True,
"run_every_day": False
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
email: 'user@example.com',
user_id: 'abc123',
slack_user_id: 'U01ABC2DEF3',
allow_already_completed: false,
start_at: '2026-02-20T09:00:00.000Z',
catch_up: true,
run_every_day: false
})
};
fetch('https://api.doozy.live/v1/tracks/{trackId}/enroll', 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.doozy.live/v1/tracks/{trackId}/enroll",
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([
'email' => 'user@example.com',
'user_id' => 'abc123',
'slack_user_id' => 'U01ABC2DEF3',
'allow_already_completed' => false,
'start_at' => '2026-02-20T09:00:00.000Z',
'catch_up' => true,
'run_every_day' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <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.doozy.live/v1/tracks/{trackId}/enroll"
payload := strings.NewReader("{\n \"email\": \"user@example.com\",\n \"user_id\": \"abc123\",\n \"slack_user_id\": \"U01ABC2DEF3\",\n \"allow_already_completed\": false,\n \"start_at\": \"2026-02-20T09:00:00.000Z\",\n \"catch_up\": true,\n \"run_every_day\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<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.doozy.live/v1/tracks/{trackId}/enroll")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"user@example.com\",\n \"user_id\": \"abc123\",\n \"slack_user_id\": \"U01ABC2DEF3\",\n \"allow_already_completed\": false,\n \"start_at\": \"2026-02-20T09:00:00.000Z\",\n \"catch_up\": true,\n \"run_every_day\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.doozy.live/v1/tracks/{trackId}/enroll")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email\": \"user@example.com\",\n \"user_id\": \"abc123\",\n \"slack_user_id\": \"U01ABC2DEF3\",\n \"allow_already_completed\": false,\n \"start_at\": \"2026-02-20T09:00:00.000Z\",\n \"catch_up\": true,\n \"run_every_day\": false\n}"
response = http.request(request)
puts response.read_body{
"object": "track_enrollment",
"track_id": "wf_abc123xyz",
"user_id": "usr_abc123",
"instance_id": "inst_xyz789",
"status": "active",
"enrolled_at": "2026-02-18T10:30:00.000Z",
"starts_at": "2026-02-20T09:00:00.000Z"
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "No such quiz: quiz_abc123",
"param": "id",
"doc_url": "https://docs.doozy.live/api/errors#resource_not_found"
}
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "No such quiz: quiz_abc123",
"param": "id",
"doc_url": "https://docs.doozy.live/api/errors#resource_not_found"
}
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "No such quiz: quiz_abc123",
"param": "id",
"doc_url": "https://docs.doozy.live/api/errors#resource_not_found"
}
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "No such quiz: quiz_abc123",
"param": "id",
"doc_url": "https://docs.doozy.live/api/errors#resource_not_found"
}
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "No such quiz: quiz_abc123",
"param": "id",
"doc_url": "https://docs.doozy.live/api/errors#resource_not_found"
}
}Authorizations
API key for authentication. Generate keys in the Doozy dashboard.
Path Parameters
The unique identifier of the track
1 - 128^[A-Za-z0-9_-]+$"wf_abc123xyz"
Body
The email address of the user to enroll
254"user@example.com"
The Doozy user ID of the user to enroll
1 - 128^[A-Za-z0-9_-]+$"abc123"
The Slack user ID of the user to enroll
1 - 128^[A-Za-z0-9_-]+$"U01ABC2DEF3"
Allow enrolling a user who has previously completed this track. Defaults to false.
false
ISO 8601 timestamp for when the user should start the track. Defaults to now. Can be set to a future date to schedule enrollment.
"2026-02-20T09:00:00.000Z"
Override the Track's catch-up setting for this enrollment. If a step's send time has passed, true makes overdue steps eligible in order; working hours can delay delivery. false shifts the Track so Day 1 starts on the next working day. Omit to inherit the Track setting.
true
Complete policy snapshot for this enrollment. Omit to inherit the resolved Track policy.
Show child attributes
Show child attributes
Deprecated compatibility override. true changes only this enrollment's working days to all seven days while preserving its inherited hours and time zone. working_hours takes precedence when both fields are sent.
false
Response
User successfully enrolled in track
The object type
track_enrollment "track_enrollment"
The ID of the track the user was enrolled in
"wf_abc123xyz"
The Doozy user ID of the enrolled user
"usr_abc123"
The ID of the workflow instance created for this enrollment
"inst_xyz789"
The status of the enrollment
active "active"
ISO 8601 timestamp of when the user was enrolled
"2026-02-18T10:30:00.000Z"
ISO 8601 timestamp of when the user will start the track (may be in the future if scheduled)
"2026-02-20T09:00:00.000Z"
Was this page helpful?