Your own UI

Replace the pixels, keep the plumbing. You draw the questions; Respondo still decides what comes next, what may be skipped, and when the answers are sent.

Take the session

Pass onSession and the built-in card never mounts. You get a session instead: read its state, subscribe to changes, and call back with answers.

survey.ts

createRespondo({
  key: "rsp_pk_…",
  surveyId: "…",
  onSession(session) {
    session.subscribe(render);
    render(session.state());

    function render(view) {
      if (view.stage === "done") return close();
      if (view.stage === "thanks") return thanks(view.thankYou);

      // view.question, view.index, view.total
      show(view.question, {
        // false means required, and the value was blank
        onAnswer: (value) => session.answer(value) || flagRequired(),
        onSkip: session.skip,
        onClose: session.dismiss,
      });
    }
  },
});

With the script tag, add data-headless to the tag and hand over a function the same way:

index.html

<script src="https://app.myrespondo.com/embed.js"
        data-key="rsp_pk_…"
        data-survey="…"
        data-headless
        defer></script>
<script>
  window.Respondo.headless(function (session) {
    // the same session as above
  });
</script>

Session

NameTypeWhat it does
state()SessionStateWhere the survey is now. See below.
subscribe(listener)() => voidCalled after every change. Returns a function that stops it.
answer(value)booleanRecord an answer and move on, following any branch. Returns false without recording when the question is required and the value is blank, so you decide how to say so.
skip()booleanMove on without answering. False if the question is required.
dismiss()voidAbandon the survey. Answers given so far are still sent.
close()voidLeave the thank-you screen.

SessionState

NameTypeWhat it does
stage"question" | "thanks" | "done"Asking, showing the thank-you, or finished.
questionQuestion | nullThe question on screen, or null once the survey is over.
indexnumberIts position, for a progress indicator.
totalnumberHow many questions there are.
thankYouThankYouSettings | nullThe title and description to show at the end, if enabled.
answersAnswer[]Everything answered so far.
surveySurveyThe whole survey, including its appearance settings.

What to pass to answer()

NameTypeWhat it does
npsnumber0 to 10.
ratingnumber1 to the question’s scale — 3, 5 or 7. ratingStyle says whether it was drawn as numbers or faces.
choicestring | string[]The chosen option, or an array of them when multiple is true. allowOther means an “Other” option with free text is allowed.
openstringFree text. placeholder carries the hint written in the editor.

A blank value — an empty string or an empty array — only counts on a question marked optional.

Keep the attribution

respondo.badge() returns the same “Powered by Respondo” link the built-in card wears, ready to append to your own.

survey.ts

footer.append(respondo.badge({ color: "#71717A" }));