curl --request POST \
--url https://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"entityType": "JOB_CANDIDATE",
"entityId": "55021"
}
'import requests
url = "https://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links"
payload = {
"entityType": "JOB_CANDIDATE",
"entityId": "55021"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({entityType: 'JOB_CANDIDATE', entityId: '55021'})
};
fetch('https://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links', 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://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links",
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([
'entityType' => 'JOB_CANDIDATE',
'entityId' => '55021'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links"
payload := strings.NewReader("{\n \"entityType\": \"JOB_CANDIDATE\",\n \"entityId\": \"55021\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"entityType\": \"JOB_CANDIDATE\",\n \"entityId\": \"55021\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"entityType\": \"JOB_CANDIDATE\",\n \"entityId\": \"55021\"\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {
"id": 8001,
"token": "bkl_9f2c1a7e4d",
"url": "https://apply.taptalent.io/book/bkl_9f2c1a7e4d",
"status": "ACTIVE",
"entityType": "JOB_CANDIDATE",
"entityId": "55021",
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@example.com",
"phone": "+15551234567",
"expiresAt": "2026-09-17T00:00:00.000Z",
"createdAt": "2026-09-10T02:00:00.000Z"
}
}Create a candidate scheduling link
Generates a unique self-scheduling link for the given entity on this
schedule, or returns its existing active link for it rather than
creating a duplicate. TapTalent resolves entityType + entityId
against the entity’s own record and snapshots its contact details
onto the link — you don’t supply name/email/phone. Share data.url
with the candidate yourself (e.g. by email or SMS from your own
system); TapTalent does not send it on your behalf.
curl --request POST \
--url https://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"entityType": "JOB_CANDIDATE",
"entityId": "55021"
}
'import requests
url = "https://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links"
payload = {
"entityType": "JOB_CANDIDATE",
"entityId": "55021"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({entityType: 'JOB_CANDIDATE', entityId: '55021'})
};
fetch('https://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links', 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://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links",
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([
'entityType' => 'JOB_CANDIDATE',
'entityId' => '55021'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links"
payload := strings.NewReader("{\n \"entityType\": \"JOB_CANDIDATE\",\n \"entityId\": \"55021\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"entityType\": \"JOB_CANDIDATE\",\n \"entityId\": \"55021\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://partner-api.taptalent.io/v1/partner/booking-schedules/{bookingScheduleId}/links")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"entityType\": \"JOB_CANDIDATE\",\n \"entityId\": \"55021\"\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {
"id": 8001,
"token": "bkl_9f2c1a7e4d",
"url": "https://apply.taptalent.io/book/bkl_9f2c1a7e4d",
"status": "ACTIVE",
"entityType": "JOB_CANDIDATE",
"entityId": "55021",
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@example.com",
"phone": "+15551234567",
"expiresAt": "2026-09-17T00:00:00.000Z",
"createdAt": "2026-09-10T02:00:00.000Z"
}
}Authorizations
Company-scoped API key. Production keys are prefixed sk_live_,
sandbox keys sk_test_, each followed by 22 base62 characters
(pattern ^sk_(live|test)_[0-9A-Za-z]{22}$). Generate keys in the
TapTalent dashboard under Account Settings → Developers → API Key
Management; a key is shown once at generation and old keys are
invalidated immediately on regeneration.
Path Parameters
Body
Creates (or, if an active link already exists for this entity on
this schedule, returns) a unique self-scheduling link. Identify the
entity to book on behalf of with entityType + entityId; TapTalent
resolves the record and snapshots its contact details onto the
resulting link — you don't provide name/email/phone yourself. The
entity must already exist (e.g. an existing job candidate, sourced
via the Job Candidates API); this
endpoint doesn't create new candidate records.
Not a fixed enum — known values today are JOB_CANDIDATE
(entityId is a jobCandidateId from the
Jobs/Candidates
APIs), OUTREACH_CAMPAIGN_CANDIDATE, and NOVA_CANDIDATE. Only
JOB_CANDIDATE ids are obtainable through this API — the other
two types are sourced entirely from TapTalent's own
campaign/onboarding flows and have no corresponding lookup here.
"JOB_CANDIDATE"
The id of the entity within entityType's source. Always a string.
"55021"
How long the generated link stays valid. Defaults to the schedule's own expiry behavior if omitted.
168
Was this page helpful?
.png?fit=max&auto=format&n=lKy84_BssSCy2hcz&q=85&s=ac7c949427cc2893306f6036415f087e)