Component and Hook Reference

Props, hooks, types, status enums, callbacks, and CSS customization for @taxbit/react-sdk. For setup, see the Integration guide.

<TaxbitQuestionnaire/> props

The primary component for collecting tax documentation. Import it from @taxbit/react-sdk and render it in your React application.

PropTypeRequiredDefaultDescription
bearerTokenstringYes*Account Owner–scoped token for API communication. Not required when demoMode is true.
questionnaire'W-FORM' | 'DPS' | 'SELF-CERT'YesWhich questionnaire to render. See Pick your questionnaire for guidance on choosing.
dataClientTaxDocumentationNoPre-collected data to populate form fields. Overrides server-fetched data if both exist.
adaptiveMode'full' | 'skipLock' | 'skipEdit'No'full'Controls how the SDK behaves when previously submitted data exists. full (default): walks through all screens with data pre-filled. skipLock: skips the form and shows a locked, read-only summary the account owner cannot change. skipEdit: skips the form and shows an editable summary for review and resubmission. See Adaptive mode.
prepopulateWithSavedDatabooleanNotrueWhen true (default), the SDK fetches the account owner's prior submission on mount, prefills the form, and routes returning users to the summary. Set to false to skip that fetch — no saved PII is requested on mount and the form starts on step one. Does not affect host-supplied data, status reads, or submission. See Skip server-side prefill.
languagestringNo'en-us' (W-FORM), 'en-gb' (DPS, SELF-CERT)Pre-selects the form language. See supported languages.
treatyClaimsbooleanNofalseW-FORM only (W-8 flows). Set to true if your clients are foreign persons claiming reduced US withholding rates under an income tax treaty. Enables treaty claim questions in W-8BEN and W-8BEN-E flows. Omit to skip treaty claims entirely.
realTimeTinValidationbooleanNofalseW-FORM only (W-9). Validates the account owner's name and TIN against the IRS in real time. The account owner can still proceed if no match. Requires RTT configuration. In demo mode, TINs containing 0 return valid, 6 return invalid, otherwise pending.
demoModebooleanNofalseRenders the form without server communication. No bearer token required. Only onProgress and onSubmit apply in demo mode. See Set up locally.
region'US' | 'EU'No'US'Routes SDK API requests to the selected Taxbit region.
dateFormat'mdy' | 'dmy' | 'ymd'No'mdy'Order of date-of-birth select inputs when displayed.
loadingComponentReactNodeNoText: "Retrieving interview status..."Custom component displayed while the SDK fetches status from the server.
poweredByTaxbitbooleanNofalseWhen true, shows "Powered by Taxbit" at the bottom of the form.
onProgress(progress: Progress) => voidNoCalled when the user navigates (Next, Back, Cancel, Submit). Receives a Progress object.
onSubmit(data: ClientTaxDocumentation) => voidNoCalled after the form passes client-side validation, before the API request completes.
onSuccess(data: ClientTaxDocumentation) => voidNoCalled after the API confirms successful submission.
onError(error: Error) => voidNoLogs to consoleCalled when the API returns an error during submission. If omitted, the error is logged to the console and shown in the SDK's error alert — not rethrown.
onSettled(data: ClientTaxDocumentation) => voidNoCalled after either onSuccess or onError.

Resubmission behavior

On mount the component fetches any prior submission for the questionnaire type and adapts:

Previous statusBehavior
COMPLETEShows the summary screen immediately for review/edit.
INCOMPLETE, prior submission existsWalks each screen with prior data pre-filled (e.g. earlier validation failure or changed requirements).
INCOMPLETE, no prior submissionWalks each screen from the start; nothing to pre-fill.
data prop + server dataThe data prop wins.

Partial progress is not saved. The SDK persists only on submit — closing or navigating away mid-flow discards entries and leaves dataCollectionStatus unchanged. The server sets INCOMPLETE when a submission fails validation or previously valid data no longer meets requirements, not on an abandoned session. Use statusData.needsResubmission as the canonical signal to route a user back through.

<TaxbitCuringDocumentation/> props

A focused component that clears specific W-8 validation issues in place. Import it from @taxbit/react-sdk. For the full embedding walkthrough, see the Curing Integration Guide.

import '@taxbit/react-sdk/style/inline.css';
import { TaxbitCuringDocumentation } from '@taxbit/react-sdk';

The component accepts one of three prop shapes. Exactly one applies per call site.

Common to all shapes

PropTypeRequiredDefaultDescription
languageLocaleNoen-usPre-selects the form language.
poweredByTaxbitbooleanNofalseRenders the "Powered by Taxbit" footer.

Demo mode

Renders against a synthesized issue list. No network calls, no token.

PropTypeRequiredDefaultDescription
demoIssueTypesCurableIssueType[]YesOpen issues to render. Status is assumed OPEN. Doc type is fixed to W-8BEN-E.
onSubmit(submission: ClientCuringSubmission) => voidNoFires when the user submits. Receives the canonical submission shape.

Production — region (default)

PropTypeRequiredDefaultDescription
bearerTokenstringYesAccount Owner–scoped token. Same token used by <TaxbitQuestionnaire />.
region'US' | 'EU'No'US'Regional server for API requests.
stagingbooleanNofalseHit the staging cluster.
loadingComponentReactNodeNonullShown during the initial status fetch.
onSuccess(submission: ClientCuringSubmission) => voidNoFires after the server accepts the multipart POST. Not when the cure is reviewed.
onError(error: Error) => voidNoLogs to consoleFires on status-fetch or submission error.
onSettled(submission: ClientCuringSubmission) => voidNoFires after onSuccess or onError, with the same payload.

Production — through a proxy

Same as region, with region and staging replaced by:

PropTypeRequiredDefaultDescription
proxyDomainstringYesRoute API requests through your own proxy instead of Taxbit directly.
proxyHeadersRecord<string, string>NoCustom headers on proxied requests; authorization and content-type are reserved.

Mount-time behavior

On mount, the component fetches statusData for the user and derives the curable issue list. The widget renders null and emits a dev-mode warning if no OPEN curable issue exists. Gate the mount on useTaxbit().needsCuringDocumentation to avoid the round-trip.

useTaxbit hook

Read a user's tax documentation status and data without rendering the form, and generate the completed document PDF. Use it to drive your own UI — for example, to decide whether to route someone into <TaxbitQuestionnaire/> or to show a "documentation complete" state.

Unlike the component, the hook has no demoMode: a valid bearerToken is always required.

Parameters

ParameterTypeRequiredDescription
bearerTokenstringYesAccount Owner–scoped token.
questionnaire'W-FORM' | 'DPS' | 'SELF-CERT'YesWhich questionnaire's data to access.
onError(error: Error) => voidNoError handler. If omitted, errors log to the console.
region'US' | 'EU'NoRegional server for API requests. Default 'US'.
proxyDomainstringNoRoute requests through your own proxy.
proxyHeadersRecord<string, string>NoCustom headers on proxied requests.

Returns

ReturnTypeDescription
statusDataClientTaxDocumentationStatus | undefinedStatus for this Account Owner (GET /tax-documentation-status).
serverDataClientTaxDocumentation | undefinedLast submitted data (GET /tax-documentation/submissions). Empty object when prepopulateWithSavedData={false}.
errorError | undefinedSet on a fetch or bearer-token error; logged unless you pass onError.
canGetDocumentUrlbooleantrue once a W-Form or Self-Cert submission is COMPLETE (false while in progress). Always false for DPS (no PDF).
generateDocumentUrl() => voidTriggers PDF URL generation.
isGeneratingDocumentUrlbooleantrue between the call and the URL being ready.
documentUrlstring | undefinedTemporary PDF URL; the hook re-polls about every 4 minutes to keep it fresh.
needsCuringDocumentationbooleantrue when the user has at least one OPEN W-Form issue the curing flow can resolve. Gate the <TaxbitCuringDocumentation /> mount on this.
isLoadingbooleantrue while the status fetch is in flight. Check before reading needsCuringDocumentation to avoid a flash of "no curing needed."
refresh() => Promise<void>Re-fetches status + submission. Resolves when both settle. Useful after a curing submit so derived state reflects the latest server view.
refreshStatus() => Promise<void>Re-fetches status only. Drives needsCuringDocumentation.
refreshSubmission() => Promise<void>Re-fetches submission only. Drives serverData.

Types

The TypeScript shapes referenced in the props and hook tables above. The SDK exports these, so you can import them for your own typing.

Progress

The object passed to your onProgress callback on every navigation event (Next, Back, Cancel, Submit). Use it to track where the user is in the flow.

type Progress = {
  language: Locale;
  percentComplete: number;
  stepId: StepId;
  stepIndex: number;   // 0-based
  stepNumber: number;  // 1-based
  stepTitle: string;   // localized
  steps: StepId[];
  totalSteps: number;
};

Common StepId values — the active sequence depends on the questionnaire and flow (Progress.steps lists what's actually shown).

StepIdAppears inNotes
accountHolderClassificationAll
accountHolderContactInformationAll
accountHolderTaxInformationAll
accountHolderTaxResidenciesConfirmationSELF-CERTTax residences in high-risk jurisdictions.
accountHolderCertificationsW-FORM
accountHolderTreatyClaimsW-FORMW-8 treaty flows.
accountHolderUsTinValidationW-FORMWhen real-time TIN validation runs.
accountHolderAdditionalInfoW-FORM
exemptionsW-FORM
regardedOwnerCertificationsW-FORMDisregarded-entity (DRE) flows only.
regardedOwnerContactInformationW-FORMDRE flows only.
regardedOwnerTaxInformationW-FORMDRE flows only.
regardedOwnerTreatyClaimsW-FORMDRE flows only.
regardedOwnerUsTinValidationW-FORMDRE flows only.
confirmationW-FORM
summaryAll

ClientTaxDocumentationStatus

Returned by useTaxbit().statusData. Each questionnaire key is undefined until data is submitted for that type.

type ClientTaxDocumentationStatus = {
  dpsQuestionnaire?: {
    dataCollectionStatus: 'COMPLETE' | 'INCOMPLETE';
    expirationDate?: string;        // 3 years after last submission
    needsResubmission?: boolean;
    vatStatus?: VatStatus;
    vatValidationDate?: string;
  };
  wFormQuestionnaire?: {
    dataCollectionStatus: 'COMPLETE' | 'INCOMPLETE';
    type: 'W-9' | 'W-8BEN' | 'W-8BEN-E' | 'W-8IMY';
    expirationDate?: string;
    issues?: QuestionnaireIssue[];
    needsResubmission?: boolean;
    tinStatus?: TinStatus;
    tinValidationDate?: string;
    treatyClaimStatus?: 'VALID' | 'INVALID';
  };
  selfCertification?: {
    dataCollectionStatus: 'COMPLETE' | 'INCOMPLETE';
    issues?: QuestionnaireIssue[];
    needsResubmission?: boolean;
  };
};

Curing types

Types used by <TaxbitCuringDocumentation/> and the curing read flow. See Reading curing statuses for how these surface in practice.

CurableIssueType

type CurableIssueType =
  | 'US_INDICIA'
  | 'TREATY_COUNTRY_MISMATCH'
  | 'CARE_OF_PERMANENT_ADDRESS'
  | 'PO_BOX_PERMANENT_ADDRESS';

Which doc types each applies to:

Issue typeW-8BENW-8BEN-EW-8IMY
US_INDICIA
TREATY_COUNTRY_MISMATCH
CARE_OF_PERMANENT_ADDRESS
PO_BOX_PERMANENT_ADDRESS

ReasonableExplanationType

type ReasonableExplanationType =
  | 'STUDENT'
  | 'TEACHER_OR_TRAINEE'
  | 'DIPLOMAT'
  | 'SPOUSE_OR_CHILD'
  | 'DO_NOT_MEET_SUBSTANTIAL_PRESENCE_TEST'
  | 'CLOSER_CONNECTION_EXCEPTION';

Only relevant when the user has an open US_INDICIA issue. The first four require no additional fields. DO_NOT_MEET_SUBSTANTIAL_PRESENCE_TEST adds the SPT day-count fields. CLOSER_CONNECTION_EXCEPTION adds the closer-connection fields.

ClientCuringSubmission

type ClientCuringSubmission = {
  fileName?: string;
  fileMimeType?: string;
  reasonableExplanationData?: {
    explanationType: ReasonableExplanationType;
    signatureName?: string;          // populated from the prior submission's accountHolder.name
    signatureDate?: string;          // ISO timestamp, stamped at submit
    // Present only when explanationType === 'DO_NOT_MEET_SUBSTANTIAL_PRESENCE_TEST'
    daysInCurrentYear?: number;
    daysInFirstPrecedingYear?: number;
    daysInSecondPrecedingYear?: number;
    weightedTotal?: number;
    // Present only when explanationType === 'CLOSER_CONNECTION_EXCEPTION'
    usPresentDaysCertified?: boolean;
    closerConnectionCountryCode?: string;
    closerConnectionReason?: string;
  };
};

Same shape across demo onSubmit and production onSuccess / onSettled.

Status enums

The string values that appear on the status fields above (tinStatus, vatStatus, and questionnaire issues). Match against them to decide what to show or do next.

TinStatus

IRS TIN validation; W-9 only.

ValueMeaning
PENDINGSubmitted, not yet validated.
VALID_SSN_MATCHSSN matches IRS records.
VALID_EIN_MATCHEIN matches IRS records.
VALID_SSN_EIN_MATCHBoth SSN and EIN match.
MISMATCHName/TIN doesn't match IRS records.
TIN_NOT_ISSUEDTIN not issued by the IRS.
INVALID_DATAData malformed or incomplete for validation.
FOREIGNForeign TIN — not validated against IRS.
ERRORIRS validation errored.

VatStatus

VIES VAT validation; DPS only.

ValueMeaning
PENDINGSubmitted, not yet validated with VIES.
VALIDVIES confirms valid for the country.
INVALIDVIES reports invalid.
INSUFFICIENT_DATANot enough data to validate.
NOT_REQUIREDUser indicated VAT not required or not issued.
NON_EUUser outside the EU — VAT validation does not apply.

Issue status

The status field on a curable W-8 issue is its current remediation state ('OPEN' | 'IN_REVIEW' | 'RESOLVED'). See Reading curing statuses.

ValueMeaning
OPENThe issue still needs to be addressed.
IN_REVIEWThe issue is being reviewed.
RESOLVEDThe issue no longer applies.

Transitions: OPEN → IN_REVIEW (filer submits), IN_REVIEW → RESOLVED (reviewer accepts), IN_REVIEW → OPEN (reviewer rejects / requests more). RESOLVED is terminal.

QuestionnaireIssue

Found on wFormQuestionnaire.issues and selfCertification.issues.

type QuestionnaireIssue = {
  issueType: IssueType;
  status: 'OPEN' | 'IN_REVIEW' | 'RESOLVED';   // present on curable W-8 issues
  createdAt: string;
  details: { field: string; description: string }[];
};
issueTypeApplies toMeaning
CARE_OF_PERMANENT_ADDRESSW-FORMPermanent address uses a c/o format.
PO_BOX_PERMANENT_ADDRESSW-FORMPermanent address is a PO Box.
US_PERMANENT_ADDRESSW-FORMW-8 filer has a US permanent address.
TREATY_COUNTRY_MISMATCHW-FORMTreaty claim country doesn't match residency.
US_INDICIAW-FORM, SELF-CERTIndicators of US-person status detected.
WITHHOLDING_DOCUMENTATIONW-FORMWithholding documentation is incomplete.
CHANGE_IN_CIRCUMSTANCESW-FORM, SELF-CERTA change in circumstances requires new documentation.
INCOMPLETE_DATAAllMissing required fields.
INCONSISTENT_DATAAllContradictory information.
INCOMPLETE_ADDRESSW-FORM, SELF-CERTAddress information is incomplete.
INCOMPLETE_CLASSIFICATIONW-FORMAccount holder classification is incomplete.
INCOMPLETE_US_TINW-FORMUS TIN is missing or incomplete.
INCOMPLETE_TREATY_CLAIMW-FORMTreaty claim information is incomplete.
CBI_RBI_CONFIRMATIONSELF-CERTCBI/RBI confirmation is required.
INCOMPLETE_GIINSELF-CERTGIIN is missing or incomplete.

SDK ↔ API endpoint mapping

The SDK makes these calls for you — useful for debugging and monitoring.

SDK actionAPI behaviorWhen
Component mounts / hook initializesGET /tax-documentation-statusOn load — checks for existing submissions.
Component mounts (data exists)GET /tax-documentation/submissionsOn load — fetches prior data for pre-fill.
User submits the formPosts form data to the submission endpointOn a valid submit.
generateDocumentUrl() requestPosts a generate-document request; returns a documentId (PROCESSING)When you call it.
generateDocumentUrl() pollingPolls (~3s) until FINISHED and a URL is availableAutomatic after the request.

The documentUrl is short-lived; the hook re-polls about every 4 minutes to refresh it before it expires.

Curing adds two calls:

SDK actionAPI behaviorWhen
Component mountsGET /tax-documentation-statusOn load — checks for OPEN curable issues.
User clicks SubmitPOST /account-owner-documents (multipart)On submit. data part is the snake_case wire body; the uploaded file is the second multipart part.

Content-Type is left to fetch so the multipart boundary survives — don't override it.

Stylesheets

The form is semantic HTML with taxbit- namespaced classes. Import one built-in stylesheet, then override classes in your own CSS.

StylesheetDescription
inline.cssFull Taxbit default styling. Best starting point — also the reference for every available class name.
basic.cssMinimal structural styling; a good base when you want full control over visual design.
minimal.cssBare minimum; use when your app's global styles should take over.

Supported languages

The language prop accepts any tag in the Locale type — the 53 codes below. The account owner can also switch language in-form (hide the dropdown with CSS). The in-form picker shows a subset: roughly 45 in DPS and Self-Certification flows and 19 in W-Form. Defaults are en-us (W-Form) and en-gb (DPS, Self-Certification).

Locale tags (53)

CodeLanguageCodeLanguageCodeLanguage
bgBulgarianfrFrenchnoNorwegian
csCzechfr-caFrench (Canada)plPolish
daDanishfr-frFrench (France)ptPortuguese
deGermanfr-luFrench (Luxembourg)pt-brPortuguese (Brazil)
de-atGerman (Austria)gaIrishpt-ptPortuguese (Portugal)
de-deGerman (Germany)hrCroatianroRomanian
elGreekhuHungarianruRussian
el-cyGreek (Cyprus)idIndonesianskSlovak
el-grGreek (Greece)itItalianslSlovenian
enEnglishjaJapanesesvSwedish
en-gbEnglish (UK)koKoreanthThai
en-nzEnglish (NZ)ltLithuaniantrTurkish
en-usEnglish (US)lvLatvianukUkrainian
esSpanishmsMalaysianviVietnamese
es-esSpanish (Spain)mtMaltesezhChinese
es-mxSpanish (Mexico)nlDutchzh-cnChinese (Simplified)
etEstoniannl-beDutch (Belgium)zh-twChinese (Traditional)
fiFinnishnl-nlDutch (Netherlands)

W-Form in-form options (19)

CodeLanguageCodeLanguage
deGermannlDutch
en-usEnglish (US)plPolish
es-mxSpanish (Mexico)pt-brPortuguese (Brazil)
fr-caFrench (Canada)roRomanian
idIndonesianruRussian
itItalianthThai
jaJapanesetrTurkish
koKoreanviVietnamese
msMalaysianzh-cnChinese (Simplified)
zh-twChinese (Traditional)

Compatibility

@taxbit/react-sdk supports React 16 through 19 (declared as a peer dependency). TypeScript type definitions are bundled with the package — no separate @types install needed.