Component and hook reference

Props, hooks, types, status enums, callbacks, and CSS customization for @taxbit/react-sdk. For setup, see the Questionnaire 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'Yes—Which questionnaire to render. See Pick your questionnaire for guidance on choosing.
dataClientTaxDocumentationNo—Pre-collected data to populate form fields. Overrides server-fetched data if both exist.
adaptiveMode'full' | 'skipLock' | 'skipEdit'No'full'How prefilled answers are used. full (default): nothing hidden; answers filled in. skipLock: questions with valid answers are hidden and locked on the summary. skipEdit: questions with valid answers are hidden, and everything stays editable on the summary. 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.
fatcabooleanNo (see notes)falseAvailable in 5.0.0 and later. W-FORM only. Enables FATCA (Chapter 4) collection: classification, certifications, GIIN capture, and substantial US owner collection where applicable. Forced to true when typesOfIncome includes INTEREST or DIVIDENDS — setting fatca={false} in that case throws at initialization. See Enable FATCA collection.
typesOfIncomeTypeOfIncome | string | (TypeOfIncome | string)[]Yes if treatyClaims—Available in 5.0.0 and later. W-FORM only. Income types the filer's account can generate. Drives treaty-eligibility filtering. Accepts hyphenated ('royalties-other') or underscored ('ROYALTIES_OTHER') forms. Unrecognized values throw at initialization. Some values (INTEREST, DIVIDENDS) also force fatca={true}. See Accepted values for the full list.
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.
eDeliveryConsentbooleanNofalseAvailable in 6.3.0 and later. W-FORM only (W-9 and every W-8). Adds a checkbox to the Review and Sign section of the summary asking the account owner to consent to receiving their tax forms electronically. The label holds the full consent statement. The box starts checked, is never required, and is never pre-filled from a prior submission. The answer is submitted as hasEDeliveryConsent (true checked, false cleared, absent when this prop is off), and config.eDeliveryConsent records whether consent was collected.
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.
proxyDomainstringNo—Routes every request through your own proxy instead of directly to Taxbit. Can't be combined with region.
proxyHeadersRecord<string, string>No—Extra headers on proxied requests. Your proxy must strip them. authorization and content-type are reserved and overwritten.
telemetrybooleanNotrueAvailable in 6.2.0 and later. Sends usage events (steps shown, button presses, validation errors shown, real-time check outcomes; never what the user typed) to telemetry/events with the same token and host as other requests. Failed events never interrupt the form. false sends nothing; demo mode sends nothing. See Usage telemetry.
dateFormat'mdy' | 'dmy' | 'ymd'No'mdy'Order of date-of-birth select inputs when displayed.
loadingComponentReactNodeNoText: "Retrieving interview status..."Shown while the SDK fetches status and the first language, and when rendered on the server.
poweredByTaxbitbooleanNofalseWhen true, shows "Powered by Taxbit" at the bottom of the form.
onProgress(progress: Progress) => voidNo—Called when the user navigates (Next, Back, Cancel, Submit). Receives a Progress object. Fires once per event, so an inline function is fine.
onSubmit(data: ClientTaxDocumentation) => voidNo—Called after the form passes client-side validation, before the API request completes. Fires whether or not the save succeeds; use onSuccess to act on a saved submission. From 6.3.0, accountHolder.phoneNumber is in E.164 form (+447872615090), and hasEDeliveryConsent is included when eDeliveryConsent is on.
onSuccess(data: ClientTaxDocumentation) => voidNo—Called after the API confirms successful submission.
onError(error: Error) => voidNoLogs to consoleCalled when the API returns an error. If omitted, the error is logged to the console and shown in the SDK's error alert — not rethrown. From 6.3.0, a failed submission keeps the form and answers on screen and shows "Your Tax Documentation could not be saved. Please try again." above Submit, so the user can retry; onError still receives the error. Not called for telemetry failures. Fires once per event, so an inline function is fine.
onSettled(data: ClientTaxDocumentation) => voidNo—Called 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[]Yes—Open issues to render. Status is assumed OPEN. Doc type is fixed to W-8BEN-E.
onSubmit(submission: ClientCuringSubmission) => voidNo—Fires when the user submits. Receives the canonical submission shape.

Production — region (default)

PropTypeRequiredDefaultDescription
bearerTokenstringYes—Account Owner–scoped token. Same token used by <TaxbitQuestionnaire />.
region'US' | 'EU'No'US'Regional server for API requests.
loadingComponentReactNodeNonullShown during the initial status fetch and the first language download.
onSuccess(submission: ClientCuringSubmission) => voidNo—Fires 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) => voidNo—Fires after onSuccess or onError, with the same payload.

Production — through a proxy

Same as region, with region replaced by:

PropTypeRequiredDefaultDescription
proxyDomainstringYes—Route API requests through your own proxy instead of Taxbit directly.
proxyHeadersRecord<string, string>No—Custom 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.
prepopulateWithSavedDatabooleanNofalse skips fetching the prior submission; serverData stays empty. Default true.
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.

useTaxbitStatus hook

A status-only version of useTaxbit. It never fetches the prior submission, so no previously submitted personal data reaches the browser. Use it when you only need to know whether the user must act, for example to decide whether to show <TaxbitCuringDocumentation />.

import { useTaxbitStatus } from '@taxbit/react-sdk';

const { needsCuringDocumentation, isLoading } = useTaxbitStatus({ bearerToken });

Parameters: bearerToken, onError, and region or proxyDomain + proxyHeaders, as for useTaxbit. It takes no questionnaire; the status covers every questionnaire.

Returns

ReturnTypeDescription
statusDataClientTaxDocumentationStatus | undefinedStatus for this Account Owner.
isLoadingbooleantrue while the status fetch is in flight.
errorError | undefinedSet on a fetch or bearer-token error.
needsCuringDocumentationbooleantrue when there's at least one OPEN curable W-8 issue.
refreshStatus() => Promise<void>Re-fetches the status. Resolves when the fetch settles.

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. Every call goes to the region's API host, or to your proxyDomain when one is set.

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.
Real-time TIN checkPosts the name and TIN for an inline matchWhen realTimeTinValidation is on.
GIIN checkPosts the GIIN for an inline checkWhen FATCA collects a GIIN.
User submits the formPosts form data to the submission endpointOn a valid submit.
Usage telemetryPosts usage events6.2.0+, unless telemetry={false} or demo mode. Failures are ignored.
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 makes these calls:

SDK actionAPI behaviorWhen
Component mountsGET /tax-documentation-statusOn load — checks for OPEN curable issues.
Component mountsGET /tax-documentation/submissionsOn load — reads the prior W-8 for the signature name. Skipped when collectSignatureName is true.
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 at most one built-in stylesheet, then override classes in your own CSS.

StylesheetLabel positionDescription
inline.cssbeside the inputFull Taxbit default styling — layout, inputs, buttons, badges.
basic.cssabove the inputSame as inline.css, with each label on its own line above the field.
minimal.cssyour choiceStructure only — form width, field spacing, status colors. Best base when you intend to restyle.
index.css—Demo-app stylesheet. Styles :root and html, so it affects your whole page. Not for production.

inline.css and basic.css declare their colors as --taxbit-color-* custom properties on :root; minimal.css declares only the four status colors. Override the tokens to theme the form.

For the token list, the full class reference and override patterns, see Customizing look and feel.

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).

Only the displayed language is downloaded. Switching language fetches the new one once and keeps the current one on screen until it arrives; if the fetch fails, the current language stays.

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. They resolve under every moduleResolution setting, including node16 / nodenext and CommonJS require, and type-check with skipLibCheck: false. For upgrade notes between versions, see the Upgrade guide.