@folaform/forms-sdk
v0.6.0
Published
Official TypeScript SDK for the Fola Form-Filling API — auto-fill USCIS, EOIR immigration court, DOL ETA/PERM, and US district court PDFs from typed JSON. 72 forms ship typed; pay-per-fill via API key.
Maintainers
Keywords
Readme
@folaform/forms-sdk
Official TypeScript SDK for the Fola Form-Filling API — auto-fill US immigration, immigration-court, labor-certification, and district-court PDFs from typed JSON, with one method per form, built-in wallet management, and zero runtime dependencies.
Runs on Node 18+ and modern browsers. Pure TypeScript, ships typed schemas for every form, fetch-based — no Axios, no node-fetch shim.
Install
npm install @folaform/forms-sdk
# or
pnpm add @folaform/forms-sdk
# or
yarn add @folaform/forms-sdkQuick start
import { FolaClient } from '@folaform/forms-sdk';
import { writeFile } from 'node:fs/promises';
const client = new FolaClient({
apiKey: process.env.FOLA_KEY!, // fk_live_… or fk_test_…
});
const result = await client.fill('i-130', {
petitioner_family_name: 'Doe',
petitioner_given_name: 'John',
beneficiary_family_name: 'Doe',
beneficiary_given_name: 'Jane',
// …intellisense lists every field, type-checks enums, dates, etc.
});
await writeFile('i-130.pdf', result.pdf);
console.log(`Charged ${result.costCents}¢ — wallet now ${result.balanceCents}¢`);What's covered
72 forms ship typed in this release, across five sectors:
| Sector | Examples | |---|---| | USCIS | I-9, I-90, I-129(F/S), I-130(A), I-131, I-134, I-140, I-192, I-290B, I-352, I-360, I-485 (+ Sup A/J), I-526(E), I-539(A), I-589, I-601, I-730, I-751, I-765(WS), I-821(D), I-824, I-829, I-864(A/EZ), I-907, I-912, I-914, I-918(A/B), AR-11, N-336, N-400, N-470, N-565, N-600, N-648 | | EOIR / Immigration Court | EOIR-26, EOIR-26A, EOIR-27, EOIR-28, EOIR-29, EOIR-33 (BIA / IC), EOIR-40, EOIR-42A, EOIR-42B | | DOL / ETA (PERM, H-2A, H-2B) | ETA-9035, ETA-9089, ETA-9141, ETA-9142A, ETA-9142B, ETA-9142C | | US District Court | AO-440 summons, JS-44 civil cover sheet, mandamus action shell | | Department of State (visa prep) | DS-160 prep, DS-260 prep | | G-forms | G-28 (attorney appearance), G-639 (FOIA), G-1145 (e-notification), G-1450 (fee) |
Tax-form coverage is intentionally not bundled in this SDK release.
API key + wallet
Generate keys and top up your wallet from the Fola workspace at
/workspace/developer.
Each fill debits a per-form rate based on complexity tier:
| Tier | Cost / fill | Examples | |---|---|---| | LARGE | 50¢ | I-485, I-589, N-400, ETA-9089 | | MEDIUM | 30¢ | I-130, I-765, EOIR-42A | | SMALL | 15¢ | G-28, G-639, AO-440 | | Mandamus | $2.00 | mandamus action shell |
Refunds are automatic if the engine errors after debiting.
Errors
import {
FolaAuthError,
FolaForbiddenError,
InsufficientBalanceError,
ValidationError,
UnknownFormError,
} from '@folaform/forms-sdk';
try {
await client.fill('i-130', { /* … */ });
} catch (err) {
if (err instanceof InsufficientBalanceError) {
console.error(`Top up — only ${err.balanceCents}¢ left, need ${err.costCents}¢`);
} else if (err instanceof ValidationError) {
// err.fieldErrors → { petitioner_family_name: 'required', ... }
console.error(err.fieldErrors);
} else if (err instanceof FolaAuthError) {
console.error('API key revoked or invalid');
} else if (err instanceof FolaForbiddenError) {
// V225 introduced per-key scopes + IP allowlist. Branch on the
// body code if you want different remediation copy:
// - 'developer_key_scope_missing' — widen scopes in the dashboard
// - 'developer_key_ip_blocked' — add the egress IP to the allowlist
// - 'developer_api_disabled' — email support to re-enable
console.error(`Forbidden (${err.code}): ${err.message}`);
} else if (err instanceof UnknownFormError) {
console.error(`No such form: ${err.formId}`);
} else throw err;
}Per-key scopes and IP allowlist
Keys minted from the
Developer Console can
carry an explicit scope set (forms:fill, forms:read,
account:read) and an optional IP allowlist (CIDR or bare IP, IPv4
- IPv6). A request that hits an endpoint outside the key's scopes
returns
403 developer_key_scope_missing; a request from a source IP outside the allowlist returns403 developer_key_ip_blocked. Both surface asFolaForbiddenErrorwith the code onerr.code, and both can be widened or cleared from the dashboard's Edit restrictions dialog without re-minting the secret.
Typed schemas
Per-form TypeScript interfaces are auto-generated from the engine's form definitions at SDK release time:
import type { I130Inputs, N400Inputs, Eta9089Inputs } from '@folaform/forms-sdk';
const inputs: I130Inputs = {
petitioner_family_name: 'Doe',
petitioner_given_name: 'John',
// intellisense lists every field, type-checks enums, dates, etc.
};
await client.fill('i-130', inputs);There's also a runtime registry for callers that need to enumerate fields generically (e.g., to scaffold a UI):
import { FORM_REGISTRY } from '@folaform/forms-sdk';
const meta = FORM_REGISTRY['i-130'];
// → { title, complexityTier, inputs: { [field]: { type, required, label, help, example, enumValues? } } }Webhooks
Subscribe to async fill / engine events with the bundled verifier:
import { verifyWebhook } from '@folaform/forms-sdk';
app.post('/fola/webhook', express.raw({ type: '*/*' }), (req, res) => {
const event = verifyWebhook({
body: req.body,
signatureHeader: req.header('Fola-Signature')!,
secret: process.env.FOLA_WEBHOOK_SECRET!,
});
// event.type → 'form.filled' | 'wallet.low_balance' | 'case.status_changed' | …
});Architecture note
This SDK is the only documented client for the Fola public API.
The REST surface (/api/public/v1/...) deliberately exposes no
schema-introspection endpoint — to discover field names, install this
SDK or read the generated TypeScript types in the published tarball.
The fill engine still validates everything server-side, so bad inputs
return field-level errors progressively without leaking the full
schema upfront.
Links
- Workspace + key management → https://folaform.com/workspace/developer
- Developer docs → https://folaform.com/developers
- Status page → https://status.folaform.com
- Issues → https://github.com/folaform/compliance-forms-engine/issues
License
Apache-2.0. See LICENSE.
