@firmadb/sdk
v0.1.0
Published
TypeScript SDK for the FirmaDB European company data API
Maintainers
Readme
FirmaDB TypeScript SDK
Official TypeScript / JavaScript client for the FirmaDB European company data API. ~25.0M entities across 18 European countries, sourced from official government registries. The precise served figure changes with every crawl — GET /v1/countries is the live number.
Works in Node 18+, Deno, Bun, and modern browsers — uses native fetch, no axios.
Install
npm install @firmadb/sdkQuickstart
import { FirmaDB } from '@firmadb/sdk';
const client = new FirmaDB({ apiKey: 'fdb_...' });
// or set FIRMADB_API_KEY in the environment and: new FirmaDB()
// Exact lookup by country + national registry id
const company = await client.companies.get({ country: 'FR', registryId: '552120222' });
console.log(company.name, company.status, company.naceCode);
// Fuzzy search
const results = await client.companies.search({ query: "Société Générale", country: 'FR', limit: 5 });
for (const hit of results.data) {
console.log(hit.match?.score, hit.name, hit.registryId);
}
// Batch enrichment (1-100 references per call, idempotent)
const batch = await client.companies.lookupBatch({
items: [
{ country: 'FR', registryId: '552120222' },
{ country: 'GB', registryId: '12345678' },
],
});
for (const row of batch.results) {
if (row.status === 'found') console.log(row.company!.name);
else console.log('not found:', row.error?.detail);
}
// Coverage / capability discovery (anonymous)
const countries = await client.countries.list();
console.log(`${countries.length} countries`);
// Account usage and rate-limit state
const usage = await client.account.usage();
console.log(usage.plan, usage.usage.consumedUnits, usage.usage.includedUnits);
console.log(client.rateLimit);Errors
Every non-2xx response is an RFC 9457 Problem Detail. The SDK throws a typed subclass of FirmaDBError. Branch on the code property, never on title or detail.
import { FirmaDB, NotFoundError, RateLimitError, InvalidCountryError } from '@firmadb/sdk';
try {
await client.companies.get({ country: 'FR', registryId: '999999999' });
} catch (e) {
if (e instanceof NotFoundError) {
console.log(e.correction);
console.log(e.countryFreshness);
} else if (e instanceof InvalidCountryError) {
console.log(e.supportedCountries);
} else if (e instanceof RateLimitError) {
console.log(e.retryAfter, e.limit);
} else throw e;
}| Status | Code | Class |
|---|---|---|
| 400 | invalid_country | InvalidCountryError |
| 400 | country_required | CountryRequiredError |
| 400 | invalid_registry_id | InvalidRegistryIdError |
| 400 | query_too_short | QueryTooShortError |
| 400 | invalid_parameter | InvalidParameterError |
| 400 | invalid_cursor | InvalidCursorError |
| 400 | batch_validation_failed | BatchValidationError |
| 401 | unauthenticated | AuthenticationError |
| 402 | payment_required | PaymentRequiredError |
| 403 | insufficient_scope | PermissionError |
| 404 | company_not_found | NotFoundError |
| 409 | idempotency_conflict | ConflictError |
| 429 | rate_limit_exceeded | RateLimitError |
| 429 | quota_exhausted | QuotaExhaustedError |
| 503 | search_unavailable / source_unavailable | ServiceUnavailableError |
Retries
The client automatically retries rate_limit_exceeded and service_unavailable responses, honoring Retry-After. Tune via maxRetries (default 3). All other 4xx are thrown immediately.
Rate-limit state
Every response refreshes client.rateLimit:
client.rateLimit.limit; // per-minute ceiling
client.rateLimit.remaining;
client.rateLimit.resetSeconds;
client.rateLimit.resource; // 'companies-read', 'companies-search', ...
client.rateLimit.creditsRemaining; // monthly verified-result quota leftMethods
| Method | Endpoint |
|---|---|
| client.companies.get({ country, registryId, include?, includeNulls? }) | GET /companies/{country}/{registry_id} |
| client.companies.search({ query, country?, nace?, status?, ..., limit?, cursor? }) | GET /companies/search |
| client.companies.lookupBatch({ items, idempotencyKey?, include? }) | POST /companies/lookup-batch |
| client.countries.list() | GET /countries |
| client.countries.get(code) | GET /countries/{code} |
| client.account.usage() | GET /account/usage |
| client.health() | GET /health |
Full reference at docs.firmadb.com.
License
MIT
