curl --request POST \
--url https://{subdomain}.conveyour.com/api/custom-reports \
--header 'Content-Type: application/json' \
--header 'x-conveyour-token: <api-key>' \
--data '
{
"class": "<string>",
"title": "<string>",
"secure": true,
"portal_visible": true,
"teams": [
"<string>"
],
"input": {}
}
'const options = {
method: 'POST',
headers: {'x-conveyour-token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
class: '<string>',
title: '<string>',
secure: true,
portal_visible: true,
teams: ['<string>'],
input: {}
})
};
fetch('https://{subdomain}.conveyour.com/api/custom-reports', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const options = {
method: 'POST',
headers: {'x-conveyour-token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
class: '<string>',
title: '<string>',
secure: true,
portal_visible: true,
teams: ['<string>'],
input: {}
})
};
fetch('https://{subdomain}.conveyour.com/api/custom-reports', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{subdomain}.conveyour.com/api/custom-reports"
payload = {
"class": "<string>",
"title": "<string>",
"secure": True,
"portal_visible": True,
"teams": ["<string>"],
"input": {}
}
headers = {
"x-conveyour-token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{subdomain}.conveyour.com/api/custom-reports",
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([
'class' => '<string>',
'title' => '<string>',
'secure' => true,
'portal_visible' => true,
'teams' => [
'<string>'
],
'input' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-conveyour-token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"status": "ok",
"message": "Custom Report created",
"data": {
"id": "507f1f77bcf86cd799439011",
"pid": "abc123def456ghi789jkl012",
"title": "Office Performance Report",
"class": "officePerformance",
"secure": true,
"portal_visible": false,
"teams": [],
"input": {
"office_id": {
"rule": "locked",
"value": ""
},
"date_range": {
"rule": "editable",
"value": "last_30_days"
}
}
}
}{
"status": "failed",
"message": "Token is either expired or does not have the correct permissions",
"data": []
}Create a custom report
Creates a new custom report template. The class must be the camelCase ID of an existing report (e.g. campaignsCampaignPerformance, officePerformance). The input field configures how each report control parameter behaves for viewers of the shared report: - locked — the value is fixed; the viewer cannot change it and the control is hidden - editable — the value is the default; the viewer can override it
Create a custom report template
curl --request POST \
--url https://{subdomain}.conveyour.com/api/custom-reports \
--header 'Content-Type: application/json' \
--header 'x-conveyour-token: <api-key>' \
--data '
{
"class": "<string>",
"title": "<string>",
"secure": true,
"portal_visible": true,
"teams": [
"<string>"
],
"input": {}
}
'const options = {
method: 'POST',
headers: {'x-conveyour-token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
class: '<string>',
title: '<string>',
secure: true,
portal_visible: true,
teams: ['<string>'],
input: {}
})
};
fetch('https://{subdomain}.conveyour.com/api/custom-reports', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const options = {
method: 'POST',
headers: {'x-conveyour-token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
class: '<string>',
title: '<string>',
secure: true,
portal_visible: true,
teams: ['<string>'],
input: {}
})
};
fetch('https://{subdomain}.conveyour.com/api/custom-reports', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{subdomain}.conveyour.com/api/custom-reports"
payload = {
"class": "<string>",
"title": "<string>",
"secure": True,
"portal_visible": True,
"teams": ["<string>"],
"input": {}
}
headers = {
"x-conveyour-token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{subdomain}.conveyour.com/api/custom-reports",
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([
'class' => '<string>',
'title' => '<string>',
'secure' => true,
'portal_visible' => true,
'teams' => [
'<string>'
],
'input' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-conveyour-token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"status": "ok",
"message": "Custom Report created",
"data": {
"id": "507f1f77bcf86cd799439011",
"pid": "abc123def456ghi789jkl012",
"title": "Office Performance Report",
"class": "officePerformance",
"secure": true,
"portal_visible": false,
"teams": [],
"input": {
"office_id": {
"rule": "locked",
"value": ""
},
"date_range": {
"rule": "editable",
"value": "last_30_days"
}
}
}
}{
"status": "failed",
"message": "Token is either expired or does not have the correct permissions",
"data": []
}Authorizations
Your API key token. Contacts endpoints require a Server-only — Full API key — see Authentication.
Query Parameters
Team scope for the request, as one or more team ObjectIds. The brackets are required: PHP keeps only the last value for a repeated plain key, so teams=A&teams=B silently resolves to B alone. On requests with a JSON body you may send teams (no brackets) in the body instead.
Values that are not valid ObjectIds are silently ignored — a mistyped team ID behaves as if no team was sent. See the teams section of the API conventions guide.
Body
The camelCase ID of the report class to render (e.g. campaignsCampaignPerformance).
Display name for this saved report configuration.
When true (default), parameters are JWT-encoded in the share URL. When false, params go as plain query strings.
When true, this report is visible to contacts via the portal. Default: false.
Team IDs that restrict access to this report. Empty array = all teams.
Map of control parameter keys to their rule and default value. Each entry: { "rule": "locked" | "editable", "value": "..." }.