J.Jupid Docs
Embed for partners

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/catalog

Use 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.

FieldTypeMeaning
idstringStable catalog row UUID.
kindarticle | tool | video | linkOrdinary Library item type.
sourcejupid_tools | jupid_blog | manual | youtube | jupid_media | jupid_siteCatalog provenance.
titlestringDisplay title.
descriptionstring | nullDisplay summary when available.
canonicalUrlstringHTTPS Jupid or external destination.
thumbnailUrlstring | nullHTTPS image URL when available.
tagsstring[]Standard catalog tags.
isPinnedbooleanStandard Library pin state.
sourceCategorystring | nullSource category when available.
metadataJSONRaw source metadata. Treat it as data, never HTML.
publishedAtstring | nullISO publication timestamp.
updatedAtstringISO row update timestamp.
videoDurationSecondsnumber | nullVideo duration when available.
presentationobject{ 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 external card opens its canonicalUrl in a new tab with noopener 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:

  1. Jupid enables your exact HTTPS origin for the catalog and registers its key.
  2. Jupid allows that origin to frame the public content at https://jupid.com.
  3. You deploy the launcher URL, key, and CSP for the same environment.
  4. 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

  1. Open the integration page on the registered Origin and confirm the library renders without a sign-in or cookie prompt.
  2. In the browser Network panel, confirm the launcher and catalog GET return 200. When the browser sends a CORS preflight, it should return 204.
  3. Search for Journal Entries 101, select its card, and confirm the real article renders in the iframe. Return to the catalog.
  4. Search for Per Diem, select its card, change a calculator input, and confirm the result updates.
  5. 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 the Origin header is absent.
  • 403 PREFLIGHT_NOT_ALLOWED: request GET with only the Authorization header. Additional request headers, including an unnecessary Content-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-src and connect-src, then confirm the nonce or style hash.
  • An iframe is blocked: confirm the API-provided content origin is in frame-src and that Jupid registered your origin for the content's frame-ancestors. Do not replace the embed URL with the canonical URL.

On this page