> For the complete documentation index, see [llms.txt](https://docs.distro.so/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.distro.so/forms/sdk.md).

# Form SDK

Use the browser SDK when your existing form or frontend needs to hand confirmed submissions to Distro and display the workflow's scheduler or redirect.

Complete [Connect an existing form](/forms/existing-forms.md) first. The connection must be activated in browser mode with the appropriate capture method and exact approved origin.

## Load the client

Use the SDK URL, connection ID, and API base shown in your connection's installation instructions.

```html
<script src="YOUR_DISTRO_ORIGIN/workflow_forms.js"></script>
<script>
  const distro = new DistroWorkflowForms({
    connectionId: "YOUR_PUBLIC_CONNECTION_ID",
    apiBase: "YOUR_DISTRO_ORIGIN",
    onError: (error) => {
      console.error(error.code, error.message);
      // Show your form's appropriate recovery message.
    }
  });
</script>
```

The public connection ID is not your API token. Keep server credentials out of browser code.

## Connect an HTML form

For a connection using **HTML form**, supply your actual submission handler:

```javascript
distro.connect("#demo-request", {
  onSubmit: async (fields, event) => {
    const result = await submitOriginalForm(fields, event);
    return { ok: result.ok === true };
  }
});
```

`submitOriginalForm` is a placeholder for your own form integration. Replace it with the code that sends the original form and confirms its success.

Return `true` or `{ ok: true }` only after confirmed success. A rejection, false result, or undefined result does not start the workflow.

The selector must match exactly one HTML form. Do not connect a form already owned by another Distro capture integration.

## Submit from a provider callback

For a connection using **Explicit SDK submission**, call this only after the provider confirms success:

```javascript
await distro.submit(
  {
    email: "alex@example.com",
    name: "Alex Example",
    company_size: 120
  },
  {
    context: {
      time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone,
      source_url: location.origin + location.pathname
    }
  }
);
```

Use the source keys and types configured in your connection. This call does not submit the original form for you.

## Handle retries

If the original form succeeded but Distro acknowledgement is unresolved, retry Distro intake for the same occurrence with `distro.retry()` where supported by the current client state.

Do not submit the original form again just to retry Distro. Keep the same fields and context for the unresolved occurrence.

A genuinely new request needs a new submission after the previous one is resolved.

## Show scheduling on another page

Configure **Display scheduler at this URL upon redirect** in Show Scheduler.

Load the same SDK and create a client for the same connection on the approved destination page. Do not submit another form there. The client restores the retained scheduling handoff.

## Server-only intake

Use the server installation example for **Run in the background**. Acquire a submission token with a stable occurrence ID, then submit the fields using that token.

Server intake cannot show a scheduler or redirect a visitor. Use browser mode for that experience.

## Verify before launch

Test original success and failure, valid and invalid fields, routing, scheduler display, booking, and an intake retry. Review the workflow Logs and the original form's destination.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.distro.so/forms/sdk.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `build a script that syncs our docs to a CMS` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
