Generate Credential (Draft)
curl --request POST \
--url https://api.thehyperstack.com/v1/credentials/generate \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"recipient": {
"name": "<string>",
"email": "<string>"
},
"group_key": "<string>",
"custom_attributes": {}
}
'import requests
url = "https://api.thehyperstack.com/v1/credentials/generate"
payload = {
"recipient": {
"name": "<string>",
"email": "<string>"
},
"group_key": "<string>",
"custom_attributes": {}
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
recipient: {name: '<string>', email: '<string>'},
group_key: '<string>',
custom_attributes: {}
})
};
fetch('https://api.thehyperstack.com/v1/credentials/generate', 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.thehyperstack.com/v1/credentials/generate",
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([
'recipient' => [
'name' => '<string>',
'email' => '<string>'
],
'group_key' => '<string>',
'custom_attributes' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"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://api.thehyperstack.com/v1/credentials/generate"
payload := strings.NewReader("{\n \"recipient\": {\n \"name\": \"<string>\",\n \"email\": \"<string>\"\n },\n \"group_key\": \"<string>\",\n \"custom_attributes\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
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.thehyperstack.com/v1/credentials/generate")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"recipient\": {\n \"name\": \"<string>\",\n \"email\": \"<string>\"\n },\n \"group_key\": \"<string>\",\n \"custom_attributes\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.thehyperstack.com/v1/credentials/generate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"recipient\": {\n \"name\": \"<string>\",\n \"email\": \"<string>\"\n },\n \"group_key\": \"<string>\",\n \"custom_attributes\": {}\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"status": "draft",
"document_id": "6f1c2a8e-3b4d-4e5f-9a7b-1c2d3e4f5a6b",
"document_url": "https://hyperstack.id/credential/6f1c2a8e-3b4d-4e5f-9a7b-1c2d3e4f5a6b",
"recipient": { "name": "Jane Doe", "email": "jane.doe@example.com" },
"group": { "title": "Cloud Security Fundamentals", "key": "Kq7Zp2LmX9aB", "code": "CSF-2026" },
"issued_on": "2026-03-15T10:30:00.412870Z",
"valid_until": null,
"metadata": { "custom_grade": "A" },
"privacy": "public"
}
{
"success": false,
"error": "Recipient Name and Email are required",
"error_code": "missing_recipient"
}
{
"success": false,
"error": "recipient must be an object with name and email",
"error_code": "invalid_recipient"
}
{
"success": false,
"error": "recipient email is not a valid email address",
"error_code": "invalid_email"
}
{
"success": false,
"error": "custom_attributes must be an object of attribute names and values",
"error_code": "invalid_custom_attributes"
}
{
"success": false,
"error": "Low balance",
"error_code": "low_balance"
}
{
"success": false,
"error": "Group Not Found",
"error_code": "group_not_found"
}
{
"success": false,
"error": "Credential already exists for this recipient, to overwrite, set duplication to true in group settings.",
"error_code": "credential_exists"
}
{
"detail": "Invalid token or organization not found"
}
Credentials
Generate Credential (Draft)
POST
/
v1
/
credentials
/
generate
Generate Credential (Draft)
curl --request POST \
--url https://api.thehyperstack.com/v1/credentials/generate \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"recipient": {
"name": "<string>",
"email": "<string>"
},
"group_key": "<string>",
"custom_attributes": {}
}
'import requests
url = "https://api.thehyperstack.com/v1/credentials/generate"
payload = {
"recipient": {
"name": "<string>",
"email": "<string>"
},
"group_key": "<string>",
"custom_attributes": {}
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
recipient: {name: '<string>', email: '<string>'},
group_key: '<string>',
custom_attributes: {}
})
};
fetch('https://api.thehyperstack.com/v1/credentials/generate', 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.thehyperstack.com/v1/credentials/generate",
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([
'recipient' => [
'name' => '<string>',
'email' => '<string>'
],
'group_key' => '<string>',
'custom_attributes' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"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://api.thehyperstack.com/v1/credentials/generate"
payload := strings.NewReader("{\n \"recipient\": {\n \"name\": \"<string>\",\n \"email\": \"<string>\"\n },\n \"group_key\": \"<string>\",\n \"custom_attributes\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
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.thehyperstack.com/v1/credentials/generate")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"recipient\": {\n \"name\": \"<string>\",\n \"email\": \"<string>\"\n },\n \"group_key\": \"<string>\",\n \"custom_attributes\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.thehyperstack.com/v1/credentials/generate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"recipient\": {\n \"name\": \"<string>\",\n \"email\": \"<string>\"\n },\n \"group_key\": \"<string>\",\n \"custom_attributes\": {}\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"status": "draft",
"document_id": "6f1c2a8e-3b4d-4e5f-9a7b-1c2d3e4f5a6b",
"document_url": "https://hyperstack.id/credential/6f1c2a8e-3b4d-4e5f-9a7b-1c2d3e4f5a6b",
"recipient": { "name": "Jane Doe", "email": "jane.doe@example.com" },
"group": { "title": "Cloud Security Fundamentals", "key": "Kq7Zp2LmX9aB", "code": "CSF-2026" },
"issued_on": "2026-03-15T10:30:00.412870Z",
"valid_until": null,
"metadata": { "custom_grade": "A" },
"privacy": "public"
}
{
"success": false,
"error": "Recipient Name and Email are required",
"error_code": "missing_recipient"
}
{
"success": false,
"error": "recipient must be an object with name and email",
"error_code": "invalid_recipient"
}
{
"success": false,
"error": "recipient email is not a valid email address",
"error_code": "invalid_email"
}
{
"success": false,
"error": "custom_attributes must be an object of attribute names and values",
"error_code": "invalid_custom_attributes"
}
{
"success": false,
"error": "Low balance",
"error_code": "low_balance"
}
{
"success": false,
"error": "Group Not Found",
"error_code": "group_not_found"
}
{
"success": false,
"error": "Credential already exists for this recipient, to overwrite, set duplication to true in group settings.",
"error_code": "credential_exists"
}
{
"detail": "Invalid token or organization not found"
}
Description
Creates a credential as a draft. Nothing is sent to the recipient, and no credit is used yet. When you are ready, publish it with Publish Credential. Drafts do not show in List Credentials or Search Credentials. Keep thedocument_id from the response, or use View Credential.
Headers
string
required
Your API key:
Bearer YOUR_API_KEY. Create a key in the Studio under Settings → Developers.Body Parameters
object
required
string
required
Key of the group to create the credential in.
object
Values for your custom attributes, such as
{"custom_grade": "A"}. Each key is the merge tag of an attribute, without brackets. You find them in the Studio under Settings → Attributes.Only attributes whose value belongs to Each credential are saved. Other keys are ignored. Values are saved as text.Success Response Fields
boolean
true when the draft was created.string
"draft".string
ID of the new credential. Use it to publish the draft.
string
The page where the credential will be, once it is published.
object
The recipient’s
name and email, as saved.object
The group’s
title, key and code.string
When the draft was created (ISO 8601, UTC).
string | null
null in this response. If the group’s credentials expire, the expiry date is set when the credential is published.object
The custom attribute values that were saved.
string
"public" or "private", from the group’s settings.Responses
{
"success": true,
"status": "draft",
"document_id": "6f1c2a8e-3b4d-4e5f-9a7b-1c2d3e4f5a6b",
"document_url": "https://hyperstack.id/credential/6f1c2a8e-3b4d-4e5f-9a7b-1c2d3e4f5a6b",
"recipient": { "name": "Jane Doe", "email": "jane.doe@example.com" },
"group": { "title": "Cloud Security Fundamentals", "key": "Kq7Zp2LmX9aB", "code": "CSF-2026" },
"issued_on": "2026-03-15T10:30:00.412870Z",
"valid_until": null,
"metadata": { "custom_grade": "A" },
"privacy": "public"
}
{
"success": false,
"error": "Recipient Name and Email are required",
"error_code": "missing_recipient"
}
{
"success": false,
"error": "recipient must be an object with name and email",
"error_code": "invalid_recipient"
}
{
"success": false,
"error": "recipient email is not a valid email address",
"error_code": "invalid_email"
}
{
"success": false,
"error": "custom_attributes must be an object of attribute names and values",
"error_code": "invalid_custom_attributes"
}
{
"success": false,
"error": "Low balance",
"error_code": "low_balance"
}
{
"success": false,
"error": "Group Not Found",
"error_code": "group_not_found"
}
{
"success": false,
"error": "Credential already exists for this recipient, to overwrite, set duplication to true in group settings.",
"error_code": "credential_exists"
}
{
"detail": "Invalid token or organization not found"
}
curl -X POST "https://api.thehyperstack.com/v1/credentials/generate" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"recipient": {
"name": "Jane Doe",
"email": "jane.doe@example.com"
},
"group_key": "Kq7Zp2LmX9aB",
"custom_attributes": {
"custom_grade": "A"
}
}'
Last modified on October 20, 2026
Was this page helpful?

