> ## Documentation Index
> Fetch the complete documentation index at: https://docs.doola.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Authenticate with the raw API key in the Authorization header. Never add a Bearer prefix.
> Use the sandbox base URL https://api.test.doola.com and a dk_test_ key in examples unless the user asks for production.
> Send an Idempotency-Key header on POST /v1/partner/customers and POST /v1/partner/companies. No other endpoint takes one.
> Every response is wrapped as {payload, error}. Read fields from payload and branch on error.code, never on the message.
> Drive formation progress from webhooks plus a reconciliation sweep, never a polling loop.
> Embedded SDK (@doola/js): the dk_ key stays on the server and mints customer sessions; the browser gets only a pk_ key and the session. onFormed carries only companyId and can fire more than once. Before charging, read the company with the dk_ key, require formationSubmissionStatus AWAITING_PAYMENT, check the owner's email, and price on the server. Then POST payment-confirmed, which answers 200 with an empty body, and replace the SDK element with a new doola.create() (never append a second one).
> The doola Formation MCP server at https://mcp.doola.com is for founders forming their own company with their own doola account. Partners integrate the Partner API or the Embedded SDK. The /mcp endpoint on this docs site only searches these docs.
> For a full capability summary with the rules above, read https://docs.doola.com/skill.md.

# FAQ

> Answers to the questions partners ask most about the doola Embedded SDK: business, payments, the founder's experience, security and integration.

Can't find your answer? Email [engineering@doola.com](mailto:engineering@doola.com). For the Partner API, see its own [FAQ](/api/faq).

## Business

<AccordionGroup>
  <Accordion title="What does a formation through the SDK include?">
    The same formation as through the Partner API: the state filing, the EIN, the registered agent and the governance document, an Operating Agreement or Bylaws. See [What is included in a formation?](/api/faq#forming-companies).
  </Accordion>

  <Accordion title="How does doola bill us for SDK formations?">
    According to your partner agreement. Nothing is filed for a formation until you confirm payment for it.
  </Accordion>

  <Accordion title="Who decides what the founder pays?">
    You do. The SDK never shows your price. The only amount the founder sees inside it is the state filing fee for their state and entity type, which the state charges, so your checkout can show the same number.
  </Accordion>

  <Accordion title="Will our customers know doola is involved?">
    The flow carries your logo, colors and font, and no "Powered by doola" line. doola's name appears only in a few places: as the included registered agent on the Addresses step and the review, in the message for an email that already has its own doola account, and in the documents themselves, which are doola's and the state's. See [What stays doola](/sdk/branding#what-stays-doola).
  </Accordion>

  <Accordion title="Can we use the SDK and the Partner API together?">
    Yes. SDK companies are ordinary companies in your partner account: you read them, download their documents and answer their required actions through the Partner API, and their webhooks arrive at the same endpoint. For new company names, the founder can also answer in the SDK.
  </Accordion>

  <Accordion title="Can we change the wizard's steps or fields?">
    No, and that is deliberate. doola keeps the wizard in line with each state's and the IRS's rules and ships changes without any work on your side. You control how it looks through [branding](/sdk/branding).
  </Accordion>
</AccordionGroup>

## Payments

<AccordionGroup>
  <Accordion title="Does doola ever charge the founder?">
    No. You charge the founder in your own checkout, with your own payment provider, at your own price. doola never sees their card.
  </Accordion>

  <Accordion title="What exactly does confirming payment mean?">
    It tells doola to start the formation. doola does not check your payment provider: `partnerReference` is stored for your reference and never verified. So you decide when to call it, for example straight after a card payment, once an invoice is paid, or right away for a free offer.
  </Accordion>

  <Accordion title="What if the founder never pays?">
    The formation stays at `AWAITING_PAYMENT`, and nothing is filed. Whenever the founder comes back to the SDK, they see that payment is pending and can reopen your checkout. To withdraw it for good, contact doola to cancel it.
  </Accordion>

  <Accordion title="How do refunds work?">
    Refunds to the founder are yours, under your own policy. If doola answers a confirmation with `409 E_COMPANY_CANCELLED`, the formation was cancelled and the payment was not applied, so refund the founder. Once you have confirmed, filing has started; contact doola about the formation if the founder wants to stop.
  </Accordion>

  <Accordion title="Can the founder add Expedited EIN or other extras?">
    Not in the SDK today. Every SDK formation is the standard formation.
  </Accordion>

  <Accordion title="Do we get a webhook when a founder submits?">
    No. The first webhook for an SDK company is `company_formation_submitted`, after you confirm payment. Your page learns about the submission through `onFormed`, so save the `companyId` with your order as soon as your checkout opens. See [Keep your records in step](/sdk/payments#keep-your-records-in-step).
  </Accordion>
</AccordionGroup>

## The founder's experience

<AccordionGroup>
  <Accordion title="Does the founder need a doola account or password?">
    No. They are signed in to your product, and your server vouches for them when it creates their session. They never see a doola sign-in.
  </Accordion>

  <Accordion title="How long does it take?">
    The wizard takes most founders a few minutes. After you confirm payment, state filing usually takes 2 to 5 business days, and the EIN follows once the state approves. The founder follows both on their dashboard.
  </Accordion>

  <Accordion title="Can a customer form more than one company?">
    Not through the SDK. Each customer forms one company, and from then on the SDK shows them that company's dashboard. A customer who already has a company in your account, including one you created through the Partner API, sees its dashboard too.
  </Accordion>

  <Accordion title="Can the founder change their details after submitting?">
    Not in the SDK. Before you confirm payment, ask doola to cancel the formation; the founder can then start again. After you confirm, contact doola.
  </Accordion>

  <Accordion title="What if the founder leaves halfway through the wizard?">
    Their progress is saved on every step. Within 7 days, in the same browser, they continue where they stopped. Any SSN or ITIN they typed is asked for again, because it is never saved.
  </Accordion>

  <Accordion title="Can founders outside the US use it?">
    Yes. Founders anywhere can form a US company. Without an SSN, they sign the IRS Form SS-4 inside the SDK after you confirm payment.
  </Accordion>

  <Accordion title="Does it work on phones?">
    Yes. On screens 640px wide or narrower, the SDK opens full screen so the keyboard never covers a field. See [Presentation and mobile](/sdk/presentation).
  </Accordion>

  <Accordion title="Which languages are supported?">
    English. When more languages ship, your integration picks them up through the `locale` option, with no change to how you embed the SDK.
  </Accordion>
</AccordionGroup>

## Data and security

<AccordionGroup>
  <Accordion title="Do SSNs or signatures pass through our systems?">
    No. The founder types them into the SDK's iframe, which is served by doola and sends them straight to doola. Your page, your servers, your error tracking and your session replay never see them. See [Security and data](/sdk/security).
  </Accordion>

  <Accordion title="What does our security team need to allow?">
    `script-src https://js.doola.com` and `frame-src https://sdk.doola.com` in your CSP, and the `doola-js` Trusted Types policy if you enforce Trusted Types. Nothing else. See [Content Security Policy](/sdk/security#content-security-policy).
  </Accordion>

  <Accordion title="Does the SDK need third-party cookies?">
    No. Sessions live in memory. Browsers that block storage in iframes still run the whole flow; the founder's unfinished wizard is then kept only until they leave the page.
  </Accordion>

  <Accordion title="What can a leaked session token do?">
    Very little. It acts as one customer, only in the SDK, for at most 10 minutes. It cannot read any other customer or call the Partner API.
  </Accordion>
</AccordionGroup>

## Integration

<AccordionGroup>
  <Accordion title="Which frameworks does it work with?">
    Any. `@doola/js` is framework-free: you append an element. [Embed the SDK](/sdk/embed) shows React, Next.js and Vue, and the session route works on any server language.
  </Accordion>

  <Accordion title="How do I show the founder's company after payment?">
    Replace the SDK element with a new one after you confirm, for example `element.replaceWith(doola.create())`. The payment screen does not watch for your confirmation by itself, and each `create()` is its own iframe, so never leave the old one on the page.
  </Accordion>

  <Accordion title="Can I track progress through the wizard?">
    Not step by step. You receive `onLoaderStart` when the SDK first shows something and `onFormed` when the founder submits.
  </Accordion>

  <Accordion title="What happens when doola updates the SDK?">
    Nothing on your side. The wizard and the loader update in place, and they stay compatible with every `@doola/js` release in the same major version. Update the package when you want new options.
  </Accordion>

  <Accordion title="How do I switch to another user on the same page?">
    Call `doola.destroy()` when the first user signs out, then `loadDoola()` again for the next one.
  </Accordion>

  <Accordion title="Are there rate limits?">
    Creating sessions is limited to 600 a minute for your partner account. Your other Partner API calls share the Partner API's limit. On `429 E_RATE_LIMITED`, wait the `Retry-After` seconds.
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="The SDK area stays blank">
    The iframe was probably blocked. Check your CSP's `frame-src` for `https://sdk.doola.com` (or `https://sdk.test.doola.com` with test keys), and look for `render_error` in `onLoadError`. See [render\_error](/sdk/reference/errors#render_error).
  </Accordion>

  <Accordion title="The founder sees 'We could not start your session'">
    Your session route failed for a reason other than a sign-out or a 409, such as a 5xx, a timeout or an invalid response. Each **Try again** calls your route again, up to three times, and every failure reaches `onAuthError` as `mint_failed`. Check your route's logs and the doola code that `onFailure` logs.
  </Accordion>

  <Accordion title="The signing panel is empty">
    Your domain is not yet on doola's list for embedded signing. Send doola every domain that hosts the SDK. Meanwhile, the founder can use the "Open it in a new tab" link.
  </Accordion>

  <Accordion title="A new user gets email_in_use">
    Their email already belongs to a doola account of their own, outside your partner account, or to a Partner Portal user (testing with your own email does this). If your route forwards only the status, any 409 arrives as `email_in_use`: forward doola's `code` so an `externalCustomerId` conflict arrives as `external_id_conflict` instead, and check `doolaCode` in your server logs.
  </Accordion>

  <Accordion title="The founder still sees Payment pending after I confirmed">
    Replace the SDK element with a new `doola.create()`. The payment screen only changes when a new element mounts.
  </Accordion>

  <Accordion title="onFormed fired twice for the same company">
    That is expected: it fires on submit and every time the founder asks to pay. Key your order and your charge on `companyId`.
  </Accordion>

  <Accordion title="My session route answers 401 although the user is signed in">
    The request probably reached your route without your sign-in cookie. If the route is on another domain than your page, call it with `credentials: 'include'` and allow that in your CORS settings.
  </Accordion>

  <Accordion title="loadDoola() rejects after a user switch">
    A different publishable key needs the old instance destroyed first. Call `doola.destroy()`, then `loadDoola()` again.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.