Business Library for partners
Add Jupid's shared public articles and tools to a partner website.
Add Jupid's public articles, calculators, videos, and links to your website with the Business Library launcher. Visitors can browse the catalog and open supported articles and tools inside your page without signing in.
The catalog is shared across partners. It contains public content, not a user's accounts or transactions. To embed a user's workspace, follow the workspace embed guide.
Open the production Business Library demo.
Before you start
Send Jupid the exact HTTPS browser origin for each environment, including its
port when present. For example, https://partner.example and
https://preview.partner.example need separate origin records and keys.
HTTP origins, paths, trailing slashes, credentials, and wildcards are not
accepted. For local testing, use an HTTPS origin registered by Jupid.
Jupid supplies a catalog key for each registered origin and enables that
origin to frame the public content. The key is visible in browser requests
and reads only public catalog metadata. Keep it out of iframe URLs and
requests to the public content site. The Origin check controls browser
access and CORS; a caller outside the browser can supply this header itself.
Production uses these exact Jupid endpoints:
- launcher:
https://app.jupid.com/partner-library/v1/launcher.js; - catalog API:
https://app.jupid.com/api/partner-library/v1/catalog; - public iframe content origin:
https://jupid.com; - a dedicated catalog key for the partner's registered
Origin.
Preview values, when provided, are separate from Production values.
Keep the key in your environment configuration and do not reuse it for another origin or partner. It must not protect private data. Coordinate key rotation with Jupid, then deploy the replacement value to your page.
Install the launcher
<div id="jupid-business-library"></div>
<script
nonce="{{requestNonce}}"
src="https://app.jupid.com/partner-library/v1/launcher.js"
></script>
<script nonce="{{requestNonce}}">
const library = window.JupidPartnerLibrary.v1.mount({
container: document.getElementById("jupid-business-library"),
accessKey: "replace-with-partner-catalog-key",
})
// Call this before the host view unmounts.
// library.destroy()
</script>Use the launcher URL and key supplied for the current environment. If your
page uses CSP nonces, replace {{requestNonce}} with its actual request nonce;
see Content Security Policy.
The launcher derives the API origin from its own script URL,
sends one cookie-free catalog request, and renders the response inside a Shadow
DOM. Calling mount again on the same container replaces the previous mount.
Call library.destroy() when the host view unmounts; it aborts an in-flight
request and removes the catalog and iframe.
The catalog keeps Jupid's standard order. Search, type, and tag filters run in the browser over the complete response, without additional API requests.
Use the API directly
The versioned endpoint is:
GET https://app.jupid.com/api/partner-library/v1/catalogUse this endpoint if you want to build your own catalog interface. Call it
from the registered browser origin with that origin's key. Omit cookies and
send the key only in the Authorization header.
const response = await fetch(
"https://app.jupid.com/api/partner-library/v1/catalog",
{
method: "GET",
credentials: "omit",
headers: {
Authorization: "Bearer replace-with-partner-catalog-key",
},
},
)
if (!response.ok) throw new Error(`Catalog request failed: ${response.status}`)
const catalog = await response.json()The browser supplies the page Origin. A request without that exact header
is rejected even when the key is correct. A server-side caller can supply
the header, so it does not prove that a request came from a browser.
An authorized GET returns 200. A CORS preflight from a registered origin
returns 204 when it requests GET with only the Authorization header. The
preflight does not authenticate the key; the GET does. Responses are private,
no-store, cookie-free, and have no ETag or credentialed CORS.
Response
The root object is { schemaVersion: 1, items: [...] }. Items remain in the
standard Business Library order.
| Field | Type | Meaning |
|---|---|---|
id | string | Stable catalog row UUID. |
kind | article | tool | video | link | Ordinary Library item type. |
source | jupid_tools | jupid_blog | manual | youtube | jupid_media | jupid_site | Catalog provenance. |
title | string | Display title. |
description | string | null | Display summary when available. |
canonicalUrl | string | HTTPS Jupid or external destination. |
thumbnailUrl | string | null | HTTPS image URL when available. |
tags | string[] | Standard catalog tags. |
isPinned | boolean | Standard Library pin state. |
sourceCategory | string | null | Source category when available. |
metadata | JSON | Raw source metadata. Treat it as data, never HTML. |
publishedAt | string | null | ISO publication timestamp. |
updatedAt | string | ISO row update timestamp. |
videoDurationSeconds | number | null | Video duration when available. |
presentation | object | { mode: "external" } or { mode: "embedded", embedUrl }. |
The response intentionally omits article body Markdown, hidden rows, generated search fields, and internal checking timestamps.
Embedded and external items
The API decides presentation from an exact canonical URL and type mapping. The launcher never derives or rewrites iframe URLs.
- Selecting an embedded article or tool card opens the API-provided public, tokenless content URL in a sandboxed iframe.
- Selecting a video, unmatched-content, or other
externalcard opens itscanonicalUrlin a new tab withnoopener noreferrer.
The iframe has referrerpolicy="no-referrer" and sandbox permissions
allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox. It is 100% of the host width and its height is
the smaller of 720 px and 80% of the viewport. The catalog uses one column on
narrow screens and two columns when the viewport is at least 720 px wide.
The launcher does not use postMessage, dynamic height, sessions, persistence,
runtime themes, or mount tokens.
Content Security Policy
Use the exact launcher/API and public content origins supplied for the current environment. The minimal source policy is:
default-src 'self';
script-src 'self' https://app.jupid.com 'nonce-{{requestNonce}}';
connect-src 'self' https://app.jupid.com;
style-src 'self' 'nonce-{{requestNonce}}';
img-src 'self' data: https:;
frame-src https://jupid.com;If the page defines script-src-elem or style-src-elem, repeat the matching
launcher source and nonce there. The launcher copies its script nonce to the
style element inside its Shadow DOM. A hash-only policy must allow the exact
hash of the launcher's inline CSS and must be updated whenever those bytes
change. Use the supplied origins without wildcards. If the page restricts
top-level navigation, allow the HTTPS destinations used by catalog links.
This is your page's policy. Separately, Jupid's content embed response allows the
registered partner origin in frame-ancestors. Canonical Jupid pages keep
their ordinary anti-framing policy and must not be used as iframe URLs.
Before launch, coordinate these steps with Jupid:
- Jupid enables your exact HTTPS origin for the catalog and registers its key.
- Jupid allows that origin to frame the public content at
https://jupid.com. - You deploy the launcher URL, key, and CSP for the same environment.
- After Jupid confirms the configuration is live, test your deployed page.
The public demo at https://developer.jupid.com/partner-library-demo has its
own caller record and key. Never reuse its key for a partner.
Five-minute smoke checklist
- Open the integration page on the registered
Originand confirm the library renders without a sign-in or cookie prompt. - In the browser Network panel, confirm the launcher and catalog GET return 200. When the browser sends a CORS preflight, it should return 204.
- Search for
Journal Entries 101, select its card, and confirm the real article renders in the iframe. Return to the catalog. - Search for
Per Diem, select its card, change a calculator input, and confirm the result updates. - Confirm the catalog has no horizontal overflow at the partner's narrowest supported width and that the browser console has no CSP or framing errors.
Troubleshooting
- 401
INVALID_ACCESS_KEY: the key is missing, stale, or belongs to a different partner record. - 403
ORIGIN_NOT_ALLOWED: scheme, host, or port does not exactly match the origin registered for this key, or theOriginheader is absent. - 403
PREFLIGHT_NOT_ALLOWED: request GET with only theAuthorizationheader. Additional request headers, including an unnecessaryContent-Type: application/json, cause the preflight to fail. - 404: Partner Library configuration is disabled or incomplete in this Jupid environment.
- 422
CATALOG_INVALID_ITEM: Jupid rejected an invalid catalog row. Contact Jupid; do not retry with a different response shape. - 503
CATALOG_UNAVAILABLE: the catalog is temporarily unavailable. - 503 from the demo page: the demo key is not configured in that docs environment. This does not indicate a problem with your own key.
- The launcher is blocked by CSP: confirm the exact launcher/API origin in
script-srcandconnect-src, then confirm the nonce or style hash. - An iframe is blocked: confirm the API-provided content origin is in
frame-srcand that Jupid registered your origin for the content'sframe-ancestors. Do not replace the embed URL with the canonical URL.