curl --request POST \
--url https://prod.skillsdbnext.com/api/v1/survey-templates \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Quarterly engagement",
"questions": [
{
"name": "Manager support",
"text": "My manager supports my development.",
"type": "rating",
"responseRequired": true,
"allowsMultipleResponses": false,
"options": [
{
"label": "Strongly agree"
}
]
}
],
"description": "Runs every quarter.",
"visibility": "visible_to_all"
}
'import requests
url = "https://prod.skillsdbnext.com/api/v1/survey-templates"
payload = {
"name": "Quarterly engagement",
"questions": [
{
"name": "Manager support",
"text": "My manager supports my development.",
"type": "rating",
"responseRequired": True,
"allowsMultipleResponses": False,
"options": [{ "label": "Strongly agree" }]
}
],
"description": "Runs every quarter.",
"visibility": "visible_to_all"
}
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({
name: 'Quarterly engagement',
questions: [
{
name: 'Manager support',
text: 'My manager supports my development.',
type: 'rating',
responseRequired: true,
allowsMultipleResponses: false,
options: [{label: 'Strongly agree'}]
}
],
description: 'Runs every quarter.',
visibility: 'visible_to_all'
})
};
fetch('https://prod.skillsdbnext.com/api/v1/survey-templates', 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://prod.skillsdbnext.com/api/v1/survey-templates",
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([
'name' => 'Quarterly engagement',
'questions' => [
[
'name' => 'Manager support',
'text' => 'My manager supports my development.',
'type' => 'rating',
'responseRequired' => true,
'allowsMultipleResponses' => false,
'options' => [
[
'label' => 'Strongly agree'
]
]
]
],
'description' => 'Runs every quarter.',
'visibility' => 'visible_to_all'
]),
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://prod.skillsdbnext.com/api/v1/survey-templates"
payload := strings.NewReader("{\n \"name\": \"Quarterly engagement\",\n \"questions\": [\n {\n \"name\": \"Manager support\",\n \"text\": \"My manager supports my development.\",\n \"type\": \"rating\",\n \"responseRequired\": true,\n \"allowsMultipleResponses\": false,\n \"options\": [\n {\n \"label\": \"Strongly agree\"\n }\n ]\n }\n ],\n \"description\": \"Runs every quarter.\",\n \"visibility\": \"visible_to_all\"\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://prod.skillsdbnext.com/api/v1/survey-templates")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Quarterly engagement\",\n \"questions\": [\n {\n \"name\": \"Manager support\",\n \"text\": \"My manager supports my development.\",\n \"type\": \"rating\",\n \"responseRequired\": true,\n \"allowsMultipleResponses\": false,\n \"options\": [\n {\n \"label\": \"Strongly agree\"\n }\n ]\n }\n ],\n \"description\": \"Runs every quarter.\",\n \"visibility\": \"visible_to_all\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://prod.skillsdbnext.com/api/v1/survey-templates")
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 \"name\": \"Quarterly engagement\",\n \"questions\": [\n {\n \"name\": \"Manager support\",\n \"text\": \"My manager supports my development.\",\n \"type\": \"rating\",\n \"responseRequired\": true,\n \"allowsMultipleResponses\": false,\n \"options\": [\n {\n \"label\": \"Strongly agree\"\n }\n ]\n }\n ],\n \"description\": \"Runs every quarter.\",\n \"visibility\": \"visible_to_all\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "58",
"name": "Quarterly engagement",
"description": "Runs every quarter.",
"visibility": "visible_to_all",
"isActive": true,
"latestVersion": {
"id": "412",
"version": "1.1",
"createdAt": "2026-09-18T09:30:00.000Z"
},
"versionCount": 2,
"questions": [
{
"id": "7001",
"questionVersionId": "410",
"questionTemplateId": "41",
"name": "Manager support",
"text": "My manager supports my development.",
"description": null,
"version": "1.0",
"type": "rating",
"responseRequired": true,
"allowsMultipleResponses": false,
"position": 1,
"options": [
{
"id": "5001",
"label": "Strongly agree",
"description": null,
"position": 1
}
]
}
],
"createdAt": "2026-09-18T09:30:00.000Z"
}
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}Create a survey template
A template and its version 1 with the given questions, in one call. Rating and text questions need no options; multiple_choice and drop_down need at least two. The response’s latestVersion.id is the templateVersionId for POST /surveys.
Requires scope: surveys:write.
curl --request POST \
--url https://prod.skillsdbnext.com/api/v1/survey-templates \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Quarterly engagement",
"questions": [
{
"name": "Manager support",
"text": "My manager supports my development.",
"type": "rating",
"responseRequired": true,
"allowsMultipleResponses": false,
"options": [
{
"label": "Strongly agree"
}
]
}
],
"description": "Runs every quarter.",
"visibility": "visible_to_all"
}
'import requests
url = "https://prod.skillsdbnext.com/api/v1/survey-templates"
payload = {
"name": "Quarterly engagement",
"questions": [
{
"name": "Manager support",
"text": "My manager supports my development.",
"type": "rating",
"responseRequired": True,
"allowsMultipleResponses": False,
"options": [{ "label": "Strongly agree" }]
}
],
"description": "Runs every quarter.",
"visibility": "visible_to_all"
}
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({
name: 'Quarterly engagement',
questions: [
{
name: 'Manager support',
text: 'My manager supports my development.',
type: 'rating',
responseRequired: true,
allowsMultipleResponses: false,
options: [{label: 'Strongly agree'}]
}
],
description: 'Runs every quarter.',
visibility: 'visible_to_all'
})
};
fetch('https://prod.skillsdbnext.com/api/v1/survey-templates', 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://prod.skillsdbnext.com/api/v1/survey-templates",
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([
'name' => 'Quarterly engagement',
'questions' => [
[
'name' => 'Manager support',
'text' => 'My manager supports my development.',
'type' => 'rating',
'responseRequired' => true,
'allowsMultipleResponses' => false,
'options' => [
[
'label' => 'Strongly agree'
]
]
]
],
'description' => 'Runs every quarter.',
'visibility' => 'visible_to_all'
]),
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://prod.skillsdbnext.com/api/v1/survey-templates"
payload := strings.NewReader("{\n \"name\": \"Quarterly engagement\",\n \"questions\": [\n {\n \"name\": \"Manager support\",\n \"text\": \"My manager supports my development.\",\n \"type\": \"rating\",\n \"responseRequired\": true,\n \"allowsMultipleResponses\": false,\n \"options\": [\n {\n \"label\": \"Strongly agree\"\n }\n ]\n }\n ],\n \"description\": \"Runs every quarter.\",\n \"visibility\": \"visible_to_all\"\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://prod.skillsdbnext.com/api/v1/survey-templates")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Quarterly engagement\",\n \"questions\": [\n {\n \"name\": \"Manager support\",\n \"text\": \"My manager supports my development.\",\n \"type\": \"rating\",\n \"responseRequired\": true,\n \"allowsMultipleResponses\": false,\n \"options\": [\n {\n \"label\": \"Strongly agree\"\n }\n ]\n }\n ],\n \"description\": \"Runs every quarter.\",\n \"visibility\": \"visible_to_all\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://prod.skillsdbnext.com/api/v1/survey-templates")
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 \"name\": \"Quarterly engagement\",\n \"questions\": [\n {\n \"name\": \"Manager support\",\n \"text\": \"My manager supports my development.\",\n \"type\": \"rating\",\n \"responseRequired\": true,\n \"allowsMultipleResponses\": false,\n \"options\": [\n {\n \"label\": \"Strongly agree\"\n }\n ]\n }\n ],\n \"description\": \"Runs every quarter.\",\n \"visibility\": \"visible_to_all\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "58",
"name": "Quarterly engagement",
"description": "Runs every quarter.",
"visibility": "visible_to_all",
"isActive": true,
"latestVersion": {
"id": "412",
"version": "1.1",
"createdAt": "2026-09-18T09:30:00.000Z"
},
"versionCount": 2,
"questions": [
{
"id": "7001",
"questionVersionId": "410",
"questionTemplateId": "41",
"name": "Manager support",
"text": "My manager supports my development.",
"description": null,
"version": "1.0",
"type": "rating",
"responseRequired": true,
"allowsMultipleResponses": false,
"position": 1,
"options": [
{
"id": "5001",
"label": "Strongly agree",
"description": null,
"position": 1
}
]
}
],
"createdAt": "2026-09-18T09:30:00.000Z"
}
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}{
"type": "https://help.skillsdb.com/api-docs/errors/validation-error",
"title": "Validation failed",
"status": 400,
"detail": "limit must be between 1 and 200",
"instance": "/api/v1/people",
"requestId": "0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e",
"errors": [
{
"field": "email",
"code": "max_length",
"message": "email must be shorter than or equal to 75 characters"
}
],
"error": "trial_expired",
"upgrade_url": "https://app.skillsdb.com/settings/billing"
}Authorizations
An API key issued by a company administrator — an environment prefix (production: sdb_live_) followed by 32 characters. The prefix identifies the environment and MUST NOT be hard-coded or validated by clients; treat the whole key as opaque. Shown exactly once at creation; only a one-way hash is stored.
Scopes (granted per key on the create screen; :write never implies :read):
skills:readskills:writepeople:readpeople:writecareers:readcareers:writetraining:readtraining:writeflags:readflags:writeorg:readorg:writeassessments:readlearning:readlearning:writecertifications:readcertifications:writeassessments:writeproficiency:readproficiency:writesurveys:readsurveys:writelabels:readlabels:write
Headers
Any unique string (at most 200 characters). Retrying with the same key and identical content replays the stored response for 24h instead of executing twice.
200Body
255"Quarterly engagement"
The questions of version 1, in order. At least one.
Show child attributes
Show child attributes
4000"Runs every quarter."
Who in the product sees the template: everyone with survey rights, or only its creator.
private, visible_to_all Response
The created resource, enveloped.
Show child attributes
Show child attributes