curl --request GET \
--url https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id}', 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.exec.com/rest/v1/knowledge-hub/pages/{page_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "p1a2b3c4d5e6",
"title": "Pricing objection guide",
"status": "published",
"visibility": "workspace",
"owner": {
"id": "u1a2b3c4d5e6",
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Smith"
},
"folders": [
{
"id": "f1a2b3c4d5e6",
"name": "Sales",
"emoji": "💼"
}
],
"skills": [
{
"id": "sk1a2b3c4d5e",
"name": "Objection handling"
}
],
"source_count": 1,
"version": 4,
"cover": "",
"published_at": "2026-06-01T12:00:00Z",
"created_at": "2026-05-01T09:00:00Z",
"updated_at": "2026-06-10T15:30:00Z",
"content": "## Handling pricing objections\n\nLead with value before discussing discounts…",
"sources": [
{
"id": "s1a2b3c4d5e6",
"title": "Q2 pricing deck.pdf",
"source_type": "upload",
"status": "ready",
"content_format": "plain_text",
"token_count": 5234,
"has_images": false,
"external_url": null,
"summary": "Quarterly pricing and packaging overview.",
"cover": "",
"folders": [
{
"id": "f9a8b7c6d5e4",
"name": "File Attachments",
"emoji": "📎"
}
],
"created_by": {
"id": "u1a2b3c4d5e6",
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Smith"
},
"created_at": "2026-05-01T09:00:00Z",
"updated_at": "2026-05-01T09:05:00Z",
"processed_at": "2026-05-01T09:05:00Z"
}
]
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "Invalid or inactive API key"
}
}{
"error": {
"type": "not_found",
"message": "Scenario not found: abc123"
}
}Get page
Returns a single page with its published markdown body, attached sources, skills, and version info.
Use ?include=draft to also return the current draft body
(draft.title and draft.content).
curl --request GET \
--url https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id}', 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.exec.com/rest/v1/knowledge-hub/pages/{page_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.exec.com/rest/v1/knowledge-hub/pages/{page_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "p1a2b3c4d5e6",
"title": "Pricing objection guide",
"status": "published",
"visibility": "workspace",
"owner": {
"id": "u1a2b3c4d5e6",
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Smith"
},
"folders": [
{
"id": "f1a2b3c4d5e6",
"name": "Sales",
"emoji": "💼"
}
],
"skills": [
{
"id": "sk1a2b3c4d5e",
"name": "Objection handling"
}
],
"source_count": 1,
"version": 4,
"cover": "",
"published_at": "2026-06-01T12:00:00Z",
"created_at": "2026-05-01T09:00:00Z",
"updated_at": "2026-06-10T15:30:00Z",
"content": "## Handling pricing objections\n\nLead with value before discussing discounts…",
"sources": [
{
"id": "s1a2b3c4d5e6",
"title": "Q2 pricing deck.pdf",
"source_type": "upload",
"status": "ready",
"content_format": "plain_text",
"token_count": 5234,
"has_images": false,
"external_url": null,
"summary": "Quarterly pricing and packaging overview.",
"cover": "",
"folders": [
{
"id": "f9a8b7c6d5e4",
"name": "File Attachments",
"emoji": "📎"
}
],
"created_by": {
"id": "u1a2b3c4d5e6",
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Smith"
},
"created_at": "2026-05-01T09:00:00Z",
"updated_at": "2026-05-01T09:05:00Z",
"processed_at": "2026-05-01T09:05:00Z"
}
]
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "Invalid or inactive API key"
}
}{
"error": {
"type": "not_found",
"message": "Scenario not found: abc123"
}
}Authorizations
API key created in Settings > API.
Format: exec_live_ followed by 40 alphanumeric characters.
Path Parameters
The page's unique identifier (UUID)
Query Parameters
Comma-separated list of optional sections to include.
Available values: draft (the current draft title and body).
"draft"
Response
Page detail
A single page with its published body, attached sources, and (optionally) its draft.
Unique page identifier (UUID)
Page title
Current page status
draft, published, archived Visibility scope of the page
private, workspace, global User who owns the page
Show child attributes
Show child attributes
Folders the page belongs to
Show child attributes
Show child attributes
Skills associated with the page
Show child attributes
Show child attributes
Number of sources attached to the page
Version number of the published version, or null if never published
Cover image reference (empty string if none)
When the page was last published
Markdown body of the published version (null if unpublished)
Sources attached to the page
Show child attributes
Show child attributes
Current draft (only included when requested via ?include=draft)
Show child attributes
Show child attributes