Integration Guide
Tax Documentation React SDK
Use Taxbit's React SDK to collect W-9, W-8, DPS, and Self-Cert documentation directly within your application.
Package: @taxbit/react-sdk on npm
| Questionnaire | Regulations | Your end user is… |
|---|---|---|
W-FORM | IRS Forms 1099, backup withholding, US FDAP treaty claims | A US person (W-9) or foreign person (W-8) |
DPS | DAC7 (EU), MRDP, UK, NZ, Canada | A seller on your digital platform |
SELF-CERT | CRS, CARF, DAC8 | A financial account holder or crypto-asset user |
For regulatory background on each questionnaire type, see Tax documentation overview.
How it works
Integrating the SDK involves server-side setup (obtaining tokens and creating Account Owners via the Taxbit API) and client-side rendering (embedding the TaxbitQuestionnaire component in your React app).
sequenceDiagram
participant Server as Your Server
participant Taxbit as Taxbit API
participant Client as Your React App
Server->>Taxbit: POST /v1/oauth/token
Taxbit-->>Server: tenant-scoped bearer token (24h)
Server->>Taxbit: POST /v1/account-owners
Taxbit-->>Server: 201 Created
Server->>Taxbit: POST /v1/oauth/account-owner-token
Taxbit-->>Server: Account Owner-scoped bearer token (24h)
Server->>Client: Pass Account Owner-scoped token
Client->>Taxbit: <TaxbitQuestionnaire /> submits form
Taxbit-->>Client: Success
A · Get the SDK running
Frontend setup. See a working form in under 5 minutes.
01 · Gather your credentials Required
RequiredLog in to the Taxbit Dashboard and navigate to Settings > Developer Settings to find your environment-specific credentials.
| Credential | Purpose |
|---|---|
client_id | Public identifier for your integration |
client_secret | Server-side only. Never expose to the browser |
tenant_id | Identifies your organization in Taxbit |
Keep your client_secret secureStore it in a secrets manager or environment variable. Anyone with the secret can impersonate your tenant.
02 · Install the SDK Required
RequiredThe SDK is published as @taxbit/react-sdk. See the npm page for the latest version.
npm install @taxbit/react-sdkCompatibility: React 16, 17, 18, 19 · TypeScript 4, 5
03 · Update your Content Security Policy If applicable
If applicableIf your app uses a Content Security Policy, add the following directive to allow the SDK to reach the Taxbit API:
connect-src https://*.taxbit.com;
Without this, the SDK will render but API calls will silently fail. Check this before testing in production.
04 · Try it in demo mode Recommended
RecommendedBefore dealing with authentication, render the SDK in demo mode. No server, no token, no API calls.
import '@taxbit/react-sdk/style/inline.css';
import { TaxbitQuestionnaire } from '@taxbit/react-sdk';
export function DemoTaxForm() {
return (
<TaxbitQuestionnaire
questionnaire="W-FORM"
demoMode
/>
);
}Demo mode works with all three questionnaire types. The form renders and accepts input, but no data is sent to a server.
If the form doesn't render, check your browser console for errors. Common issues include missing CSS imports and React version conflicts.
Testing TIN validation in demo mode: TINs containing 0 return valid, 6 return invalid, all others return pending. See Component and hook reference for details.
05 · Render the questionnaire component Required
RequiredOnce you have a bearer token from your backend (see Phase B), swap demoMode for a real bearerToken.
import '@taxbit/react-sdk/style/inline.css';
import { TaxbitQuestionnaire } from '@taxbit/react-sdk';
export function TaxFormStep({ bearerToken }) {
return (
<TaxbitQuestionnaire
bearerToken={bearerToken}
questionnaire="W-FORM" // "DPS" | "SELF-CERT" | "W-FORM"
language="en-us"
onSuccess={(data) => console.log('submitted', data)}
/>
);
}
Where to embedConsider embedding the SDK at the end of your onboarding process or in the Account Profile / Settings section so tax documentation collection feels like a natural part of account creation.
Mobile appsThe SDK is a web-based solution. For native mobile apps, open an in-app webview that loads the SDK.
Adaptive Mode for returning usersSet
adaptiveMode="skipLock"to lock pre-filled fields as read-only, or"skipEdit"to let users update them. This turns a multi-screen form into a 2-click confirmation. See Adaptive mode.
See Component and hook reference for the full props table.
B · Connecting the backend
Server-side setup. Tokens, Account Owners, and the security boundary.
Key API endpoints
| Method | Endpoint | Purpose |
|---|---|---|
POST | /v1/oauth/token | Tenant-scoped bearer token |
POST | /v1/account-owners | Create an Account Owner |
POST | /v1/oauth/account-owner-token | Account Owner-scoped bearer token for the SDK |
Base URL: https://api.multi1.enterprise.taxbit.com. This is the same for both sandbox and production environments. Your credentials determine which environment you are working in.
06 · Request a tenant-scoped bearer token Required
RequiredThe tenant-scoped token lets your server create Account Owners. Valid for 24 hours.
| Method | Endpoint |
|---|---|
POST | /v1/oauth/token |
// Server-side — Node.js
const response = await fetch(
"https://api.multi1.enterprise.taxbit.com/v1/oauth/token",
{
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: process.env.TAXBIT_CLIENT_ID,
client_secret: process.env.TAXBIT_CLIENT_SECRET,
tenant_id: process.env.TAXBIT_TENANT_ID,
}),
}
);
const { access_token: tenantToken } = await response.json();
Server-side onlyThis request must be made from your backend. Browser-based requests will be declined to keep your
client_secretconfidential.
Cache this tokenCache the 24-hour tenant token server-side. Only fetch Account Owner-scoped tokens when initializing the SDK, not on every login or page transition.
07 · Create an Account Owner Required
RequiredOnly id and account_owner_type are required.
| Method | Endpoint |
|---|---|
POST | /v1/account-owners |
// Server-side — Node.js
const aoResponse = await fetch(
"https://api.multi1.enterprise.taxbit.com/v1/account-owners",
{
method: "POST",
headers: {
"Authorization": `Bearer ${tenantToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
id: "d290f1ee-6c54-4b01-90e6-d701748f0851", // V4 UUID recommended
account_owner_type: "INDIVIDUAL", // INDIVIDUAL or ENTITY
}),
}
);The id you provide becomes the account_owner_id in all subsequent API calls.
Provisioning strategyNew users: Create the Account Owner during onboarding, when the user creates their account in your system. Only IDs needed.
Existing users: Both API and file ingestion are available for backfilling existing Account Owner data.
Account creation is optional for the SDKThe SDK does not require an Account. You may need Accounts later for transaction reporting. See Accounts API.
08 · Generate an Account Owner-scoped token Required
RequiredThe SDK needs a token scoped to a single Account Owner.
| Method | Endpoint |
|---|---|
POST | /v1/oauth/account-owner-token |
// Server-side — Node.js
const aoTokenResponse = await fetch(
"https://api.multi1.enterprise.taxbit.com/v1/oauth/account-owner-token",
{
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: process.env.TAXBIT_CLIENT_ID,
client_secret: process.env.TAXBIT_CLIENT_SECRET,
tenant_id: process.env.TAXBIT_TENANT_ID,
account_owner_id: "d290f1ee-6c54-4b01-90e6-d701748f0851", // from Step 07
}),
}
);
const { access_token: aoToken } = await aoTokenResponse.json();
// Pass aoToken to your client. Use it as bearerToken in Step 05
Token expirationBoth the tenant token and Account Owner token are valid for 24 hours. If a token expires mid-session, API calls return
401 Unauthorized. Handle this in youronErrorcallback by requesting a fresh token from your backend and re-initializing the SDK.
C · Customize & enhance
Production polish. Callbacks, styling, pre-fill, and more.
09 · Wire up callbacks Recommended
RecommendedHook into the SDK lifecycle for analytics, routing, and error handling.
<TaxbitQuestionnaire
bearerToken={bearerToken}
questionnaire="W-FORM"
onProgress={(p) => analytics.track('tax_step', p)}
onSubmit={(data) => console.log('submitting', data)}
onSuccess={(data) => router.push('/onboarding/done')}
onError={(err) => Sentry.captureException(err)}
onSettled={() => setSubmitting(false)}
/>See Component and hook reference for the Progress object and all callback signatures.
Do not rely on client-side callbacks for compliance stateUsers can close their browser before
onSuccessfires. Do not use client-side callbacks to update critical compliance records in your database. Use webhooks for definitive status changes.
Handling re-submissionsCheck
statusData.needsResubmissionvia theuseTaxbithook on login or key flows. Surface a banner or blocking screen whentrue. UseadaptiveMode="skipEdit"(not"skipLock") for re-submission so users can update changed info. Only notify when action is needed.
10 · Style the SDK to match your brand Recommended
RecommendedPick a starter stylesheet and override what you need.
// Three built-in options
import '@taxbit/react-sdk/style/inline.css'; // fully styled (recommended)
import '@taxbit/react-sdk/style/basic.css'; // neutral baseline
import '@taxbit/react-sdk/style/minimal.css'; // almost unstyled/* Override to match your brand */
.taxbit-button {
background: #0B1B33;
border-radius: 8px;
}
.taxbit-input:focus {
outline: 2px solid #2EE5C8;
}
Design tipUse a lightweight frame around the SDK. Avoid popups, cookie consent banners, or notification overlays that might confuse the user or obstruct the form. Align fonts, colors, and layout to match your native design.
See Component and hook reference for the full CSS guide, and Adaptive mode for branded examples.
Mobile webview embedding
The Taxbit React SDK is a web-based solution built with HTML5 and React. For native mobile apps, load the SDK inside a webview. The SDK handles the full tax documentation flow within the webview, and your native app controls the surrounding experience.
How it works:
- Prepare a webpage that hosts the
TaxbitQuestionnairecomponent along with your JavaScript code. This page will listen to SDK events (callbacks). - Load this webpage in a webview and set up native code bindings so your app can receive events from the SDK.
- Configure your JavaScript to call native callback methods when the SDK fires events like
onSuccess,onError, oronProgress.
Webview components by platform:
| Platform | Component | Docs |
|---|---|---|
| React Native | react-native-webview | GitHub |
| Flutter | webview_flutter | pub.dev |
| iOS (native) | WKWebView | Apple Developer |
| Android (native) | android.webkit.WebView | Android Developer |
Communicating between the webview and your native app:
For Android, use JavaScript interface bindings to call native Android code from your webview. See the official Android documentation on binding JavaScript to Android code.
For iOS, use WKUserContentController to set up message handlers that receive events from JavaScript running in the webview. See the Apple documentation on WKUserContentController.
Performance and cachingPre-warm the webview. Webviews take time to spin up. Instantiate and load the URL off-screen before the user navigates to the tax documentation screen. On Android Custom Tabs, call
CustomTabsClient.warmup().Deferred rendering. To avoid dropping UI frames (jank), delay rendering heavy webview content until native screen animations and transitions are completely finished.
Enable DOM storage. Set
domStorageEnabled(Android) or equivalent local storage settings so the SDK can cache assets locally for faster load times on repeat visits.
User experienceFallback handling. Always handle network connection losses gracefully. Intercept loading errors (
onReceivedErroron Android,didFailProvisionalNavigationon iOS) and present a clean, native "Offline" screen rather than a generic browser error page.Visual continuity. Web content often pops into view abruptly. Mask this by implementing a native progress bar or shimmer skeleton screen that stays active until the page completely finishes rendering.
Responsive viewports. Ensure the embedded HTML contains a mobile-first viewport meta tag:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">to prevent unwanted desktop-style layout sizing.Form input handling. On mobile, keyboard behavior can obscure form fields. Test that the webview scrolls correctly when the keyboard opens, especially for address and TIN input fields.
11 · Pre-fill form data you already have Optional
OptionalPass data you already collected via the data prop so users only confirm what's already there.
const prefillData = {
accountHolder: {
name: 'Jane Smith',
isUsPerson: true,
accountOwnerType: 'INDIVIDUAL',
address: {
firstLine: '742 Evergreen Terrace',
city: 'Springfield',
stateOrProvince: 'IL',
postalCode: '62704',
country: 'US',
},
},
};<TaxbitQuestionnaire data={prefillData} bearerToken={bearerToken} questionnaire="W-FORM" />The data prop takes priority over server-fetched data. See Component and hook reference for the full type.
12 · Enable PDF download Optional
OptionalAfter submission, give users a download of their completed W-9, W-8, or Self-Cert. DPS does not support PDF.
import { useTaxbit } from '@taxbit/react-sdk';
function DownloadButton({ bearerToken }) {
const {
canGetDocumentUrl, generateDocumentUrl,
isGeneratingDocumentUrl, documentUrl,
} = useTaxbit({ bearerToken, questionnaire: 'W-FORM' });
useEffect(() => {
if (canGetDocumentUrl) generateDocumentUrl();
}, [canGetDocumentUrl]);
if (!canGetDocumentUrl) return null;
return documentUrl
? <a href={documentUrl} download>Download tax form</a>
: <button disabled>Generating PDF…</button>;
}Where to go next
- Component and hook reference — Props, hook return values, TypeScript types, status enums, CSS, supported languages
- Adaptive mode — Pre-fill and skip/lock for returning users, branded integration examples
- Tax documentation overview — Regulatory background for W-FORM, DPS, and Self-Cert questionnaires
- Webhooks guide — Tax documentation status change events for background monitoring
- npm package —
@taxbit/react-sdk, latest version and changelog - API reference — All Taxbit API endpoints
Updated 1 day ago
