Skip to content

Embed a survey for a known user

Show a published survey inside your product and tie each response to your own user id.

A respondent link is anonymous: anyone who opens it can answer, and the response carries no identity. An embed session is the opposite - it is created for one user you already identify, and the id you supply travels with the response all the way to your webhook.

The flow

  • Your server asks Asqiro for an embed session, passing your own user id.
  • Asqiro returns a URL that is valid for one hour.
  • Your page loads that URL in an iframe.
  • The response Asqiro stores carries your externalUserId, and so does the response.completed event.

Create the session server-side

Create the session in the request that renders the page, on your server. The API key must never reach the browser: anyone holding it can read every survey and response in the workspace.

Creating a session for the signed-in user
javascript
const SURVEY_ID = "s_7t2qk8wvbf31";

export async function createEmbedSession(externalUserId) {
  const response = await fetch(
    `https://www.asqiro.com/api/v1/surveys/${SURVEY_ID}/embed-sessions`,
    {
      method: "POST",
      headers: {
        authorization: `Bearer ${process.env.ASQIRO_API_KEY}`,
        "content-type": "application/json",
      },
      body: JSON.stringify({ externalUserId }),
    },
  );

  if (!response.ok) {
    const { error } = await response.json();
    throw new Error(`Asqiro embed session failed: ${error.code}`);
  }

  // { embedUrl, expiresAt }
  return response.json();
}

Load it in an iframe

Use the returned embedUrl exactly as given. It already carries both the embed flag that renders the survey without site chrome and the session token, so appending or rewriting query parameters will break it.

Embedding the returned URL
html
<iframe
  src="https://www.asqiro.com/f/s_7t2qk8wvbf31?embed=1&embedSession=lM3q..."
  width="100%"
  height="720"
  style="border: 0"
  title="Onboarding feedback"
></iframe>
Note Give the iframe a title that names the survey. Screen reader users otherwise land in an unlabelled frame with no idea what it contains.

Read the identity back

externalUserId appears on the response in the responses endpoint and in the data of the response.completed webhook event. Join on it to attach the answers to the user record you already have.

json
{
  "id": "r_9fk21bqz4m",
  "surveyId": "s_7t2qk8wvbf31",
  "externalUserId": "user_8812",
  "completed": true,
  "completedAt": "2026-08-13T10:24:07.980Z",
  "createdAt": "2026-08-13T10:21:55.114Z",
  "answers": [{ "fieldId": "f_title", "value": "Weekly" }]
}

Rules worth knowing

  • The survey must be published. A draft or closed survey answers 400 with the code invalid_request.
  • The URL expires one hour after it is created. Create one per user per visit rather than storing it.
  • A session is bound to the one survey it was created for. It cannot be reused for another.
  • externalUserId is any non-empty string up to 256 characters. Use your own stable identifier, not an email address or anything else you would not want stored alongside the answers.
  • Creating a session needs an API key whose creator can edit the workspace. A viewer's key answers 403.