Guide

Embedding

Show access requests inside your client portal, resize the iframe to fit, and react to progress with browser events.

Clients can grant access without leaving your portal: show their request in an iframe. The embedded page updates as they sign in, grant access and fill in the intake form, and tells your page what happens.

Add the iframe

Every request has an embedUrl: its link with ?mode=embed. Get it from POST /requests or GET /requests/{id}, or from Embed code in a request’s menu in the dashboard.

<iframe
  id="agencyaccess"
  src="https://acme.agencyaccess.co/i/2f6d8a14-91c3-4b7e-a5d0-8e3f1c6b9a72?mode=embed"
  title="Grant access"
  style="width: 100%; height: 700px; border: 0">
</iframe>

Signing in with Google, Meta and the other platforms opens in a pop-up, because platforms don’t allow sign-in inside iframes. When the client finishes, the pop-up closes after a few seconds and the embedded page updates within a few seconds; if signing in fails, the pop-up shows the error. If the browser blocks the pop-up, the page sends an error event and offers to sign in in a new tab instead, or to open the whole page in a new tab; either way the embedded page updates when the client comes back.

  • Let your page open pop-ups. If you sandbox the iframe, include allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox.
  • The link works for anyone who has it, like the request’s normal link. Show it only to the client it belongs to.
  • If the request has a redirectUrl, the thank-you screen shows a button that opens it inside the iframe, so use a page that can be framed, or leave it out and react to request.completed instead.
  • The embedded page re-reads the request when it becomes visible again and once a minute while it is visible, so changes made elsewhere (such as you cancelling the request) show up on their own.

Browsers

Embedding does not rely on third-party cookies or on storage shared between the iframe and the sign-in window, so it is designed to keep working under browsers’ tracking protection (such as Safari’s and Firefox’s). Clients need JavaScript, and pop-ups or new tabs for signing in.

Listen for events

The embedded page sends events to your page with postMessage, only to your page’s exact origin. Check that a message comes from your iframe and from AgencyAccess before using it:

const frame = document.getElementById("agencyaccess")

window.addEventListener("message", (event) => {
  if (event.source !== frame.contentWindow) return
  if (!/^https:\/\/([a-z0-9-]+\.)?agencyaccess\.co$/.test(event.origin)) return
  const message = event.data
  if (message?.source !== "agencyaccess" || message.version !== 1) return

  switch (message.type) {
    case "resize":
      frame.style.height = `${message.data.height}px`
      break
    case "request.completed":
      showNextStep(message.requestId)
      break
  }
})

Every message looks like { source: "agencyaccess", version: 1, type, eventId, requestId, data }. ready reports the request’s status when the page loads; the other events describe what changes after that.

EventWhendata
readyThe page loadedstatus: the request’s status
resizeThe page’s height changedheight in pixels (at most 20,000)
auth.requiredThe client needs to sign in to a platformplatform
service.grantedA service was grantedplatform, service
service.grant_failedGranting a service failedplatform, service
intake.completedThe intake form was submitted
request.completedThe request is completestatus
request.cancelledThe request was cancelledstatus
request.expiredThe request passed its deadlinestatus
errorSomething went wrong for the client, such as a sign-in that could not startcontext, platform, message

Browser events are for updating your interface. Confirm outcomes on your server with webhooks or the API, since anything running in the browser can be tampered with.

When your page hides its origin

The embedded page finds your origin from the browser. Some browsers, such as Firefox, report it only through the referrer. If your portal sends no referrer (for example Referrer-Policy: no-referrer), add your origin to the link so events can still reach you. The parameter only directs events; it is not permission to embed (see below).

https://acme.agencyaccess.co/i/2f6d8a14-...?mode=embed&parentOrigin=https://portal.example.com

By default your links can be embedded on any site. To allow only your own, an agency owner adds your portal’s origins in the dashboard under API > Embedding and turns on Only allow these sites to embed my access links (both need a plan with API access). Origins are exact, such as https://portal.example.com (https only, no paths or wildcards; http://localhost and http://127.0.0.1, on any port, work for development), up to 20. The same page lists the sites your links have been seen embedded on.

  • On other sites, the page shows a message with a link to open it directly, and sends no events. AgencyAccess’s own sites are always allowed. Access pages are restricted too.
  • With the restriction on and no origins added, links can’t be embedded anywhere.
  • The page checks where it is embedded using what the browser reports. With the restriction on, keep your portal’s referrer on (the default strict-origin-when-cross-origin is enough): some browsers, such as Firefox, report the framing site only through it.

Restricting embedding doesn’t make links private: anyone with a link can still open it directly.