Django CMS · Schema

Django CMS Page Content

JSON Schema for a Django CMS page content object as returned by the djangocms-rest API

CMSContent ManagementDjangoPythonHeadless CMSREST APIOpen-SourcePagesPluginsPlaceholders

Properties

Name Type Description
title string Page title
page_title string Page title used in the HTML tag; falls back to title</td> </tr> <tr> <td><span class="prop-name">menu_title</span></td> <td><span class="prop-type">string</span></td> <td>Title displayed in navigation menus; falls back to title</td> </tr> <tr> <td><span class="prop-name">meta_description</span></td> <td><span class="prop-type">string</span></td> <td>SEO meta description for the page</td> </tr> <tr> <td><span class="prop-name">redirect</span></td> <td><span class="prop-type">stringnull</span></td> <td>Redirect URL if configured; null when no redirect is set</td> </tr> <tr> <td><span class="prop-name">absolute_url</span></td> <td><span class="prop-type">string</span></td> <td>Absolute frontend URL for the page</td> </tr> <tr> <td><span class="prop-name">path</span></td> <td><span class="prop-type">string</span></td> <td>Relative URL path of the page (e.g. 'blog/my-post')</td> </tr> <tr> <td><span class="prop-name">details</span></td> <td><span class="prop-type">string</span></td> <td>API endpoint URL for this page</td> </tr> <tr> <td><span class="prop-name">is_home</span></td> <td><span class="prop-type">boolean</span></td> <td>Whether this is the home/root page</td> </tr> <tr> <td><span class="prop-name">login_required</span></td> <td><span class="prop-type">boolean</span></td> <td>Whether the page requires authentication to view</td> </tr> <tr> <td><span class="prop-name">in_navigation</span></td> <td><span class="prop-type">boolean</span></td> <td>Whether the page appears in navigation menus</td> </tr> <tr> <td><span class="prop-name">soft_root</span></td> <td><span class="prop-type">boolean</span></td> <td>Whether the page acts as a soft root for navigation</td> </tr> <tr> <td><span class="prop-name">template</span></td> <td><span class="prop-type">string</span></td> <td>Template file used to render this page</td> </tr> <tr> <td><span class="prop-name">xframe_options</span></td> <td><span class="prop-type">string</span></td> <td>X-Frame-Options header value for this page</td> </tr> <tr> <td><span class="prop-name">limit_visibility_in_menu</span></td> <td><span class="prop-type">booleannull</span></td> <td>Whether menu visibility is restricted by user auth state</td> </tr> <tr> <td><span class="prop-name">language</span></td> <td><span class="prop-type">string</span></td> <td>Language code for this page content (e.g. 'en', 'de')</td> </tr> <tr> <td><span class="prop-name">languages</span></td> <td><span class="prop-type">array</span></td> <td>All languages this page is available in</td> </tr> <tr> <td><span class="prop-name">is_preview</span></td> <td><span class="prop-type">boolean</span></td> <td>Whether this response was served in preview/draft mode</td> </tr> <tr> <td><span class="prop-name">application_namespace</span></td> <td><span class="prop-type">stringnull</span></td> <td>Application namespace if the page is an apphook; null otherwise</td> </tr> <tr> <td><span class="prop-name">creation_date</span></td> <td><span class="prop-type">string</span></td> <td>ISO 8601 timestamp when the page was first created</td> </tr> <tr> <td><span class="prop-name">changed_date</span></td> <td><span class="prop-type">string</span></td> <td>ISO 8601 timestamp when the page was last modified</td> </tr> <tr> <td><span class="prop-name">placeholders</span></td> <td><span class="prop-type">array</span></td> <td>Ordered list of placeholders defined by the page template</td> </tr> </tbody> </table> </div> <div style="margin-top: 2rem;"> <a href="https://github.com/api-evangelist/django-cms/blob/main/json-schema/djangocms-page-content-schema.json" target="_blank" rel="noopener" class="btn btn-outline-dark btn-sm">View JSON Schema on GitHub</a> </div> <link rel="stylesheet" href="/assets/prism/prism-coy.min.css"> <link rel="stylesheet" href="/assets/prism/prism-line-numbers.min.css"> <style> .src-widget { background: #fdfdfd; border: 1px solid #e3e7ee; border-radius: 10px; overflow: hidden; margin-top: 0.75rem; } .src-widget-head { display: flex; align-items: center; gap: 0.5rem; padding: 0.55rem 0.85rem; background: #f8fafc; border-bottom: 1px solid #e3e7ee; flex-wrap: wrap; } .src-label { color: #475569; font-weight: 600; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 0.8rem; flex: 0 0 auto; } .src-picker { flex: 0 0 auto; max-width: 360px; padding: 0.3em 0.55em; border: 1px solid #cbd5e1; border-radius: 4px; background: #fff; font-size: 0.78rem; color: #1a1a2e; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; cursor: pointer; } .src-picker:focus { outline: none; border-color: #1e40af; box-shadow: 0 0 0 2px rgba(30, 64, 175, 0.15); } .src-loading { color: #94a3b8; font-style: italic; padding: 1rem; } .src-search { flex: 1 1 200px; min-width: 140px; } .src-search input { width: 100%; padding: 0.3em 0.6em; border: 1px solid #cbd5e1; border-radius: 4px; font-size: 0.8rem; background: #fff; color: #1a1a2e; } .src-search input:focus { outline: none; border-color: #1e40af; box-shadow: 0 0 0 2px rgba(30, 64, 175, 0.15); } .src-actions { display: flex; gap: 0.25rem; flex: 0 0 auto; } .src-actions a, .src-actions button { background: none; border: 1px solid transparent; padding: 0.25em 0.6em; color: #1e40af; font-size: 0.78rem; font-weight: 500; cursor: pointer; text-decoration: none; border-radius: 4px; line-height: 1.4; } .src-actions a:hover, .src-actions button:hover { background: #eef2f7; } .src-actions button.active { background: #dbeafe; border-color: #93c5fd; } .src-actions button:disabled { color: #94a3b8; cursor: not-allowed; } .src-actions button:disabled:hover { background: none; } .src-widget pre[class*="language-"] { margin: 0; padding: 1rem 0; background: #fdfdfd; box-shadow: none; border: none; max-height: 540px; overflow: auto; font-size: 0.82rem; line-height: 1.5; } .src-widget pre[class*="language-"] > code { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; padding-right: 1rem; } .src-widget pre[class*="language-"]::before, .src-widget pre[class*="language-"]::after { display: none; } .src-widget pre.line-numbers { padding-left: 3.5em; counter-reset: linenumber; position: relative; } .src-widget pre.line-numbers > code { position: relative; white-space: inherit; } .src-widget pre.line-numbers .line-numbers-rows { position: absolute; pointer-events: none; top: 1rem; font-size: 100%; left: -3em; width: 2.7em; letter-spacing: -1px; border-right: 1px solid #e3e7ee; user-select: none; } .src-widget pre.line-numbers .line-numbers-rows > span { display: block; counter-increment: linenumber; } .src-widget pre.line-numbers .line-numbers-rows > span:before { content: counter(linenumber); color: #cbd5e1; display: block; padding-right: 0.7em; text-align: right; font-size: 0.78rem; } .src-widget .token.key, .src-widget .token.property, .src-widget .token.atrule { color: #1e40af; font-weight: 600; } .src-widget .token.string { color: #047857; } .src-widget .token.number, .src-widget .token.boolean, .src-widget .token.null { color: #b45309; } .src-widget .token.comment { color: #94a3b8; font-style: italic; } .src-widget .token.punctuation, .src-widget .token.operator { color: #64748b; } .src-widget .token.tag { color: #7c3aed; } .src-widget .token.anchor, .src-widget .token.alias { color: #be185d; } .src-widget mark.src-hit { background: #fef08a; color: inherit; padding: 0; border-radius: 2px; } .src-widget mark.src-hit-active { background: #fb923c; color: #fff; } .src-copied { color: #047857 !important; } .src-empty { padding: 2rem 1rem; text-align: center; color: #94a3b8; font-size: 0.85rem; } </style> <h3 class="section-title" id="source">JSON Schema</h3> <div class="src-widget" data-src-widget data-original-lang="json" data-current-lang="json" data-original-filename="djangocms-page-content-schema.json"> <div class="src-widget-head"> <span class="src-label" data-src-filename>djangocms-page-content-schema.json</span> <span class="src-search"> <input type="search" data-src-search placeholder="Search in source… (n / N to navigate)" aria-label="Search source"> </span> <span class="src-actions"> <button type="button" data-src-toggle data-target="yaml" aria-label="View as YAML">YAML</button> <button type="button" data-src-toggle data-target="json" aria-label="View as JSON">JSON</button> <button type="button" data-src-download aria-label="Download source">Download</button> <a data-src-raw href="https://raw.githubusercontent.com/api-evangelist/django-cms/refs/heads/main/json-schema/djangocms-page-content-schema.json" target="_blank" rel="noopener">Raw ↑</a> <button type="button" data-src-copy>Copy</button> </span> </div> <pre class="line-numbers language-json"><code class="language-json" data-src-code>{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://raw.githubusercontent.com/api-evangelist/django-cms/main/json-schema/djangocms-page-content-schema.json", "title": "Django CMS Page Content", "description": "JSON Schema for a Django CMS page content object as returned by the djangocms-rest API", "type": "object", "properties": { "title": { "type": "string", "maxLength": 255, "description": "Page title" }, "page_title": { "type": "string", "maxLength": 255, "description": "Page title used in the HTML <title> tag; falls back to title" }, "menu_title": { "type": "string", "maxLength": 255, "description": "Title displayed in navigation menus; falls back to title" }, "meta_description": { "type": "string", "description": "SEO meta description for the page" }, "redirect": { "type": ["string", "null"], "maxLength": 2048, "description": "Redirect URL if configured; null when no redirect is set" }, "absolute_url": { "type": "string", "format": "uri", "description": "Absolute frontend URL for the page" }, "path": { "type": "string", "maxLength": 200, "description": "Relative URL path of the page (e.g. 'blog/my-post')" }, "details": { "type": "string", "format": "uri", "description": "API endpoint URL for this page" }, "is_home": { "type": "boolean", "description": "Whether this is the home/root page" }, "login_required": { "type": "boolean", "description": "Whether the page requires authentication to view" }, "in_navigation": { "type": "boolean", "description": "Whether the page appears in navigation menus" }, "soft_root": { "type": "boolean", "description": "Whether the page acts as a soft root for navigation" }, "template": { "type": "string", "maxLength": 100, "description": "Template file used to render this page" }, "xframe_options": { "type": "string", "maxLength": 50, "description": "X-Frame-Options header value for this page" }, "limit_visibility_in_menu": { "type": ["boolean", "null"], "default": false, "description": "Whether menu visibility is restricted by user auth state" }, "language": { "type": "string", "maxLength": 10, "description": "Language code for this page content (e.g. 'en', 'de')", "examples": ["en", "de", "fr", "zh-cn"] }, "languages": { "type": "array", "items": { "type": "string", "maxLength": 10 }, "description": "All languages this page is available in" }, "is_preview": { "type": "boolean", "default": false, "description": "Whether this response was served in preview/draft mode" }, "application_namespace": { "type": ["string", "null"], "maxLength": 200, "description": "Application namespace if the page is an apphook; null otherwise" }, "creation_date": { "type": "string", "format": "date-time", "description": "ISO 8601 timestamp when the page was first created" }, "changed_date": { "type": "string", "format": "date-time", "description": "ISO 8601 timestamp when the page was last modified" }, "placeholders": { "type": "array", "items": { "$ref": "#/definitions/Placeholder" }, "description": "Ordered list of placeholders defined by the page template" } }, "required": [ "title", "page_title", "menu_title", "meta_description", "absolute_url", "path", "details", "is_home", "login_required", "in_navigation", "soft_root", "template", "language", "languages", "creation_date", "changed_date" ], "definitions": { "Placeholder": { "type": "object", "title": "Placeholder", "description": "A CMS placeholder containing structured plugin content for a given slot", "properties": { "slot": { "type": "string", "description": "Template slot name identifying this placeholder" }, "label": { "type": "string", "description": "Human-readable label for the placeholder" }, "language": { "type": "string", "description": "Language code of the placeholder content" }, "content": { "type": "array", "items": { "$ref": "#/definitions/PluginInstance" }, "description": "Ordered list of serialized plugin data objects" }, "details": { "type": "string", "format": "uri", "description": "Direct API URL for this placeholder" }, "html": { "type": "string", "default": "", "description": "Server-rendered HTML for the placeholder (only present when ?html=1 is requested)" } }, "required": ["slot", "label", "language", "details"] }, "PluginInstance": { "type": "object", "title": "PluginInstance", "description": "A serialized CMS plugin instance within a placeholder", "properties": { "plugin_type": { "type": "string", "description": "Plugin class name (e.g. 'TextPlugin', 'PicturePlugin')" }, "pk": { "type": "integer", "description": "Primary key of the plugin instance" }, "parent_plugin_type": { "type": ["string", "null"], "description": "Parent plugin type if this is a child plugin; null for root plugins" } }, "required": ["plugin_type"], "additionalProperties": true } } } </code></pre> </div> <script src="/assets/prism/prism-core.min.js" defer></script> <script src="/assets/prism/prism-yaml.min.js" defer></script> <script src="/assets/prism/prism-json.min.js" defer></script> <script src="/assets/prism/prism-line-numbers.min.js" defer></script> <script src="/assets/prism/js-yaml.min.js" defer></script> <script> (function () { if (window.__srcWidgetInit) return; window.__srcWidgetInit = true; function initWidget(widget) { var codeEl = widget.querySelector('[data-src-code]'); var preEl = widget.querySelector('pre'); var search = widget.querySelector('[data-src-search]'); var toggles = widget.querySelectorAll('[data-src-toggle]'); var downloadBtn = widget.querySelector('[data-src-download]'); var copyBtn = widget.querySelector('[data-src-copy]'); var fileLabel = widget.querySelector('[data-src-filename]'); var picker = widget.querySelector('[data-src-picker]'); var rawLink = widget.querySelector('[data-src-raw]'); var headingEl = widget.previousElementSibling && widget.previousElementSibling.tagName === 'H3' ? widget.previousElementSibling : null; var fetchedCache = {}; // Original raw text — we always re-render from this so toggles + searches don't compound. var originalLang = widget.dataset.originalLang; var originalText = codeEl.textContent; var originalFilename = widget.dataset.originalFilename; var currentLang = originalLang; var currentText = originalText; var searchHits = []; var activeHit = -1; function highlight() { if (window.Prism) window.Prism.highlightElement(codeEl); } function setActiveToggle() { toggles.forEach(function (b) { if (b.dataset.target === currentLang) b.classList.add('active'); else b.classList.remove('active'); }); } function updateFilenameForLang() { if (!fileLabel) return; var base = (currentSourceFilename || originalFilename).replace(/\.(ya?ml|json)$/i, ''); fileLabel.textContent = base + '.' + currentLang; } var currentSourceFilename = originalFilename; var currentSourceUrl = null; if (rawLink) currentSourceUrl = rawLink.getAttribute('href'); function setLangContent(lang, text) { currentLang = lang; currentText = text; codeEl.textContent = text; codeEl.className = 'language-' + lang; preEl.className = 'line-numbers language-' + lang; highlight(); setActiveToggle(); updateFilenameForLang(); runSearch(); } function tryConvert(targetLang) { if (targetLang === currentLang) return; if (!window.jsyaml) return; try { var parsed; if (currentLang === 'yaml') parsed = window.jsyaml.load(currentText); else parsed = JSON.parse(currentText); var out; if (targetLang === 'yaml') { out = window.jsyaml.dump(parsed, { indent: 2, lineWidth: 100, noRefs: true }); } else { out = JSON.stringify(parsed, null, 2); } setLangContent(targetLang, out); } catch (err) { alert('Cannot convert: source is not valid ' + currentLang.toUpperCase() + '.\n' + err.message); } } // ---- Search highlighting (DOM walker over text nodes inside <code>) ---- function clearSearch() { widget.querySelectorAll('mark.src-hit').forEach(function (m) { var parent = m.parentNode; while (m.firstChild) parent.insertBefore(m.firstChild, m); parent.removeChild(m); parent.normalize(); }); searchHits = []; activeHit = -1; } function runSearch() { clearSearch(); var q = (search.value || '').trim(); if (q.length < 2) return; var qLower = q.toLowerCase(); var walker = document.createTreeWalker(codeEl, NodeFilter.SHOW_TEXT, null); var nodes = []; var n; while ((n = walker.nextNode())) nodes.push(n); nodes.forEach(function (node) { var text = node.nodeValue; var lower = text.toLowerCase(); var idx = lower.indexOf(qLower); if (idx === -1) return; var frag = document.createDocumentFragment(); var cursor = 0; while (idx !== -1) { if (idx > cursor) frag.appendChild(document.createTextNode(text.slice(cursor, idx))); var mark = document.createElement('mark'); mark.className = 'src-hit'; mark.textContent = text.slice(idx, idx + q.length); frag.appendChild(mark); searchHits.push(mark); cursor = idx + q.length; idx = lower.indexOf(qLower, cursor); } if (cursor < text.length) frag.appendChild(document.createTextNode(text.slice(cursor))); node.parentNode.replaceChild(frag, node); }); if (searchHits.length) jumpToHit(0); } function jumpToHit(i) { if (!searchHits.length) return; if (activeHit >= 0 && searchHits[activeHit]) searchHits[activeHit].classList.remove('src-hit-active'); activeHit = ((i % searchHits.length) + searchHits.length) % searchHits.length; var el = searchHits[activeHit]; el.classList.add('src-hit-active'); el.scrollIntoView({ block: 'center', behavior: 'smooth' }); } // ---- Wire up ---- var debounce; search.addEventListener('input', function () { clearTimeout(debounce); debounce = setTimeout(runSearch, 100); }); search.addEventListener('keydown', function (ev) { if (ev.key === 'Enter' || ev.key === 'n') { ev.preventDefault(); jumpToHit(activeHit + 1); } else if (ev.key === 'N' || (ev.key === 'p')) { ev.preventDefault(); jumpToHit(activeHit - 1); } else if (ev.key === 'Escape') { search.value = ''; runSearch(); } }); toggles.forEach(function (b) { b.addEventListener('click', function () { tryConvert(b.dataset.target); }); }); downloadBtn.addEventListener('click', function () { var blob = new Blob([codeEl.textContent], { type: currentLang === 'json' ? 'application/json' : 'application/yaml' }); var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = fileLabel.textContent; document.body.appendChild(a); a.click(); document.body.removeChild(a); setTimeout(function () { URL.revokeObjectURL(url); }, 0); }); copyBtn.addEventListener('click', function () { navigator.clipboard.writeText(codeEl.textContent).then(function () { var orig = copyBtn.textContent; copyBtn.textContent = 'Copied'; copyBtn.classList.add('src-copied'); setTimeout(function () { copyBtn.textContent = orig; copyBtn.classList.remove('src-copied'); }, 1500); }); }); // ---- Picker (provider pages with multiple specs) ---- function applySource(text, lang, filename, url, heading) { currentSourceFilename = filename || originalFilename; currentSourceUrl = url || null; if (rawLink) { if (url) { rawLink.setAttribute('href', url); rawLink.style.display = ''; } else { rawLink.style.display = 'none'; } } if (headingEl && heading) headingEl.textContent = heading; setLangContent(lang, text); } if (picker) { picker.addEventListener('change', function () { var opt = picker.options[picker.selectedIndex]; var url = opt.dataset.url; var fmt = opt.dataset.format || 'yaml'; var fname = opt.dataset.filename || ''; var heading = opt.dataset.heading || ''; if (!url) { // Original embedded source applySource(originalText, originalLang, originalFilename, picker.options[0].dataset.url || null, picker.options[0].dataset.heading || ''); return; } if (fetchedCache[url]) { applySource(fetchedCache[url], fmt, fname, url, heading); return; } codeEl.textContent = 'Loading ' + fname + '…'; codeEl.className = ''; preEl.className = ''; fetch(url).then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); }).then(function (text) { fetchedCache[url] = text; applySource(text, fmt, fname, url, heading); }).catch(function (err) { codeEl.textContent = 'Could not load: ' + err.message; }); }); // Stash the default option's url so we can restore "Raw" link when reset. if (rawLink && picker.options[0]) { picker.options[0].dataset.url = rawLink.getAttribute('href') || ''; picker.options[0].dataset.heading = (headingEl ? headingEl.textContent : '') || ''; } } // Auto-fetch when initial source is empty but a remote URL is available. // This happens when the build found an external OpenAPI URL but didn't // inline the content — the widget fetches it on page load instead. if (!originalText.trim() && currentSourceUrl) { var remoteUrl = currentSourceUrl; codeEl.textContent = 'Loading…'; codeEl.className = ''; preEl.className = 'line-numbers language-' + originalLang; fetch(remoteUrl) .then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); }) .then(function (text) { var ext = remoteUrl.replace(/\?.*/, '').split('.').pop().toLowerCase(); var fmt = ext === 'json' ? 'json' : 'yaml'; originalText = text; originalLang = fmt; currentLang = fmt; widget.dataset.originalLang = fmt; applySource(text, fmt, originalFilename, remoteUrl, headingEl ? headingEl.textContent : ''); }) .catch(function (err) { codeEl.textContent = 'Could not load spec: ' + err.message; }); } // Initial state setActiveToggle(); // Wait for Prism to load before highlighting / line-numbers wiring. var tries = 0; var waitPrism = setInterval(function () { if (window.Prism && window.Prism.plugins) { clearInterval(waitPrism); highlight(); } else if (++tries > 80) { clearInterval(waitPrism); } }, 50); } function initAll() { document.querySelectorAll('[data-src-widget]').forEach(initWidget); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initAll); } else { initAll(); } })(); </script> <h2 class="section-anchor" id="api-mcp"><a href="#api-mcp">Work with this as data</a></h2> <p class="section-blurb"> Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.</p> <div class="card-grid"> <div class="item-card" style="border-left: 3px solid #3098d8;"> <h4>MCP server</h4> <p class="text-muted small mb-2">One button, every client — Claude, Cursor, VS Code and the rest.</p> <script src="https://install.apicommons.org/button.js" async></script> <mcp-install-button server="https://apis.io/server.json" label="Install the MCP server" color="#3098d8"></mcp-install-button> <p class="text-muted small mb-0 mt-2"><code>https://apis.io/mcp</code></p> </div> <div class="item-card" style="border-left: 3px solid #6d28d9;"> <h4>Tools for schemas</h4> <details> <summary class="small text-muted" style="cursor:pointer;">4 MCP tools reach this</summary> <ul class="list-unstyled small mt-2 mb-0"> <li class="mb-2"><code>find_json_schemas</code><span class="d-block text-muted">Browse and filter every JSON Schema in the catalog.</span></li> <li class="mb-2"><code>apis_io_search</code><span class="d-block text-muted">START HERE — APIs, providers and tags for one query, each with its total.</span></li> <li class="mb-2"><code>resolve</code><span class="d-block text-muted">Turn a domain, URL or GitHub org into the provider it belongs to.</span></li> <li class="mb-2"><code>find_cohorts</code><span class="d-block text-muted">Every scored population of providers in the catalog.</span></li> </ul> </details> <a href="https://apis.io/developer/mcp-server/" class="btn btn-sm btn-outline-secondary mt-2">All 92 tools</a> </div> <div class="item-card" style="border-left: 3px solid #198754;"> <h4>Call it yourself</h4> <details> <summary class="small text-muted" style="cursor:pointer;">curl for this page</summary> <div class="mt-2"> <span class="text-muted small d-block mb-1">This JSON Schema</span> <pre class="small mb-0" style="white-space:pre-wrap;word-break:break-all;"><code>curl "https://apis.io/api/v1/json-schemas/djangocms-page-content"</code></pre> </div> <div class="mt-2"> <span class="text-muted small d-block mb-1">All schemas</span> <pre class="small mb-0" style="white-space:pre-wrap;word-break:break-all;"><code>curl "https://apis.io/api/v1/json-schemas?limit=25"</code></pre> </div> </details> <p class="text-muted small mb-0 mt-2">Discovery needs no key. Ratings and market analysis are Pro.</p> </div><div class="item-card" style="border-left: 3px solid #6c757d;"> <h4>Get an API key</h4> <p class="text-muted small mb-2">Free tier, no email required.</p> <div class="d-flex flex-column gap-2"> <a href="https://apis.io/api/v1/auth/login?provider=github" class="btn btn-sm btn-outline-secondary d-flex align-items-center justify-content-center gap-2"> <svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z"/></svg> <span>GitHub</span> </a> <a href="https://apis.io/api/v1/auth/login?provider=google" class="btn btn-sm btn-outline-secondary d-flex align-items-center justify-content-center gap-2"> <svg viewBox="0 0 18 18" width="16" height="16" aria-hidden="true"><path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62Z"/><path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.81.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18Z"/><path fill="#FBBC05" d="M3.97 10.72a5.41 5.41 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33Z"/><path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58C13.46.89 11.43 0 9 0A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58Z"/></svg> <span>Google</span> </a> <a href="https://apis.io/api/v1/auth/login?provider=linkedin" class="btn btn-sm btn-outline-secondary d-flex align-items-center justify-content-center gap-2"> <svg viewBox="0 0 24 24" width="16" height="16" fill="#0A66C2" aria-hidden="true"><path d="M20.45 20.45h-3.56v-5.57c0-1.33-.03-3.04-1.85-3.04-1.85 0-2.14 1.45-2.14 2.94v5.67H9.35V9h3.41v1.56h.05c.48-.9 1.63-1.85 3.36-1.85 3.6 0 4.27 2.37 4.27 5.45v6.29ZM5.34 7.43a2.06 2.06 0 1 1 0-4.13 2.06 2.06 0 0 1 0 4.13ZM7.12 20.45H3.55V9h3.57v11.45ZM22.22 0H1.77C.79 0 0 .77 0 1.72v20.56C0 23.23.79 24 1.77 24h20.45c.98 0 1.78-.77 1.78-1.72V1.72C24 .77 23.2 0 22.22 0Z"/></svg> <span>LinkedIn</span> </a> </div> <p class="text-muted small mb-0 mt-2">A second provider on the same verified email joins the account you already have.</p> </div> </div> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://apis.io/" }, { "@type": "ListItem", "position": 2, "name": "Django CMS", "item": "https://apis.io/providers/django-cms/" }, { "@type": "ListItem", "position": 3, "name": "Django CMS Page Content" } ] } </script> </main> <footer class="footer"> <div class="container"><div class="footer-grid"><div class="footer-col"> <h6 class="footer-col-title">Catalog</h6> <ul class="footer-col-list"><li><a href="https://apis.io/providers/">Providers</a></li><li><a href="https://apis.io/apis/">APIs</a></li><li><a href="https://apis.io/tags/">Tags</a></li><li><a href="https://apis.io/industries/">Industries</a></li><li><a href="https://apis.io/areas/">Areas</a></li><li><a href="https://apis.io/regions/">Regions</a></li><li><a href="https://apis.io/countries/">Countries</a></li></ul> </div><div class="footer-col"> <h6 class="footer-col-title">Artifacts</h6> <ul class="footer-col-list"><li><a href="https://apis.io/extensions/">OpenAPI Extensions</a></li><li><a href="https://apis.io/headers/">HTTP Headers</a></li><li><a href="https://apis.io/schemas/">Schemas</a></li><li><a href="https://apis.io/examples/">Examples</a></li><li><a href="https://apis.io/json-structure/">JSON Structure</a></li><li><a href="https://apis.io/collections/">Collections</a></li><li><a href="https://apis.io/arazzos/">Arazzo Workflows</a></li><li><a href="https://apis.io/servers/">MCP Servers</a></li><li><a href="https://apis.io/a2a/">A2A Agent Cards</a></li><li><a href="https://apis.io/ard/">Agent Discovery</a></li><li><a href="https://apis.io/agent-skills/">Agent Skills</a></li></ul> </div><div class="footer-col"> <h6 class="footer-col-title">Signals</h6> <ul class="footer-col-list"><li><a href="https://apis.io/rating/">Kin Score</a></li><li><a href="https://apis.io/security/">Security Posture</a></li><li><a href="https://apis.io/scopes/">OAuth Scopes</a></li><li><a href="https://apis.io/agentic-access/">Agentic Access</a></li><li><a href="https://apis.io/plans/">Plans</a></li><li><a href="https://apis.io/rate-limits/">Rate Limits</a></li><li><a href="https://apis.io/finops/">FinOps</a></li></ul> </div><div class="footer-col"> <h6 class="footer-col-title">Platform</h6> <ul class="footer-col-list"><li><a href="https://apis.io/developer/">Developer Docs</a></li><li><a href="https://apis.io/unlock/">Data Access</a></li><li><a href="https://apis.io/insights/">Insights</a></li><li><a href="https://apis.io/analytics/">Analytics</a></li><li><a href="https://apis.io/search-terms/">Search Terms</a></li><li><a href="https://apis.io/roadmap/">Roadmap</a></li><li><a href="https://apis.io/changelog/">Changelog</a></li></ul> </div><div class="footer-col"> <h6 class="footer-col-title">APIs.io</h6> <ul class="footer-col-list"><li><a href="https://apis.io/about/">About</a></li><li><a href="https://apis.io/blog/">Blog</a></li><li><a href="https://usecommune.com/n/apisio">Newsletter</a></li><li><a href="https://apis.io/add/">Add Your API</a></li><li><a href="https://apis.io/support/">Support</a></li><li><a href="https://github.com/api-search">GitHub</a></li></ul> </div></div><div class="footer-bar"> <span class="footer-copy">© APIs.io</span> <div class="footer-legal"><a href="http://apisjson.org">APIs.json</a><a href="http://apicommons.org">API Commons</a><a href="https://apievangelist.com">API Evangelist</a><a href="https://apis.io/terms/">Terms</a><a href="https://apis.io/privacy/">Privacy</a></div> </div> </div> </footer> <script src="/assets/js/kin-glyph.js"></script> </body> </html>