The visualization endpoints turn a GraphJSON query configuration into an embeddable iframe URL, and optionally an image URL.
Generate an iframe URL#
POST https://api.graphjson.com/api/visualize/iframe
const response = await fetch(
"https://api.graphjson.com/api/visualize/iframe",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
api_key: process.env.GRAPHJSON_API_KEY,
collection: "product_events",
IANA_time_zone: "UTC",
graph_type: "Single Line",
start: "30 days ago",
end: "now",
filters: [["event", "=", "signup_completed"]],
metric: null,
aggregation: "Count",
compare: "30 days ago",
granularity: "Day",
customizations: {
title: "Daily signups",
lineColor: "#7c3aed",
secondaryColor: "#9ca3af",
showYAxis: true,
showDots: false
}
})
}
);
const body = await response.json();
if (!response.ok) {
throw new Error(body.error || `GraphJSON returned ${response.status}`);
}
console.log(body.url);
Response:
{
"url": "https://graphjson.com/embed?p=..."
}
The URL contains an encrypted query configuration. The iframe loads live data when requested.
Render the iframe#
<iframe
src="https://graphjson.com/embed?p=..."
title="Daily signups"
width="100%"
height="360"
loading="lazy"
style="border: 0;"
></iframe>
Generate iframe and image URLs#
POST https://api.graphjson.com/api/visualize/embed
This endpoint accepts the same visualization payload and returns:
{
"iframe_url": "https://graphjson.com/embed?p=...",
"image_url": "https://graphjson.com/api/image?p=..."
}
Use the iframe for interactive web display. Use the image URL where a raster representation is required, and verify its output for your target size before placing it in a report.
Request fields#
The query fields match the Data API:
collectionIANA_time_zonegraph_typestartandendfiltersaggregation,metric, andsplitgranularityandcompare- specialized ratio and comparison filters
The visualization endpoint does not validate every chart field before generating the URL. Test the resulting embed, not only the URL response.
Customizations#
Customization support varies by graph type. Common fields include:
| Field | Type | Purpose |
|---|---|---|
title |
string | Chart title |
lineColor |
string | Primary line color |
secondaryColor |
string | Comparison line color |
backgroundColor |
string | Chart background |
showYAxis |
boolean | Show the y-axis |
showDots |
boolean | Show points on a line |
hideXAxis |
boolean | Hide the x-axis |
hideToolTip |
boolean | Disable chart tooltips |
hideSummary |
boolean | Hide summary values |
hideMissing |
boolean | Avoid filling missing time buckets with zero |
value_prefix |
string | Prefix for displayed values |
value_suffix |
string | Suffix for displayed values |
Build and customize the chart in the dashboard first, then export its payload. That is the authoritative way to get the customization set supported by a specific graph type.
Dynamic filters#
Generate a URL per authorized account:
const filters = [
["event", "=", "report_exported"],
["account_id", "=", authenticatedAccountId]
];
Derive authenticatedAccountId from the server session. Never allow a browser to choose an arbitrary filter without an authorization check.
Security model#
Security: The API request contains the workspace key and must run on a trusted server. The returned iframe or image URL is a bearer capability: anyone with it can view that configured result.
Do not expose an unfiltered sensitive chart. Avoid logging complete generated URLs, and scope caches by tenant when URLs are personalized.
SQL visualizations#
The endpoint also accepts sql_query with graph type and column mappings. Use the same mapping fields documented under Data API → Run saved-style SQL.