# FirmAPI – SDKs & Libraries

Official client libraries to integrate FirmAPI into your application in minutes. Both SDKs support sandbox mode for testing without an API key.

## No API key needed

Both SDKs include a sandbox mode that lets you test without an API key and without rate limits. The sandbox returns demo data and works the same as the production API.

```php
use FirmApi\Client;

$client = Client::sandbox();

// Or via env (Laravel):  FIRMAPI_SANDBOX=true
// Or plain PHP:  define('FIRMAPI_SANDBOX', true); before new Client(...)

// Works the same as production
$company = $client->companies->byIco('51636549')->get();
```

```javascript
import { FirmApi } from 'firmapi';

const client = FirmApi.sandbox();

// Or: new FirmApi({ apiKey, sandbox: true }), or FIRMAPI_SANDBOX=true env (Node)

// Works the same as production
const company = await client.companies.byIco('51636549');
```

The sandbox uses demo data and the URL firmapi.sk/v1/sandbox. All methods work the same as in production, so when you're done testing, simply replace Client::sandbox() / FirmApi.sandbox() with normal initialization using your API key.

## PHP SDK

Official PHP client for FirmAPI. Requires PHP 8.1+ and supports Laravel auto-discovery.

### Installation

```bash
composer require firmapi/phpsdk:^2.0
```

This documentation covers SDK v2.x. Upgrading from v1.x? See the SDK CHANGELOG for the breaking changes – fast-by-default (cached) data, typed responses, and the internal-ID lookup removed.

### Quick Start

**Lookup by ICO**

```php
use FirmApi\Client;

// Create a client with your API key
$client = new Client('your-api-key');

// Look up a company by ICO (base data only)
$company = $client->companies->byIco('51636549')->get();

echo $company['data']['name'];         // "Version Two s. r. o."
echo $company['data']['address'];       // "Bratislava ..."

// Include enrichment data with fluent methods
$company = $client->companies->byIco('51636549')
    ->withTax()
    ->withFinancials()
    ->withDebtorStatus()
    ->get();

echo $company['data']['tax']['dic'];          // "2120733417"
echo $company['data']['financials']['net_turnover']; // 486210

// Or get everything at once
$full = $client->companies->byIco('51636549')->withAll()->get();
```

**Search**

```php
// Search by name
$results = $client->search->byName('Version Two');

foreach ($results['data'] as $company) {
    echo $company['ico'] . ' - ' . $company['name'];
}

// Autocomplete (Select2-compatible)
$suggestions = $client->search->autocomplete('vers', limit: 5);

// Advanced multi-field search
$results = $client->search->advanced([
    'name' => 'Version',
    'city' => 'Bratislava',
]);
```

**Batch Lookup** (Requires Starter plan or higher)

```php
// Batch lookup by ICO
$batch = $client->batch->byIco(['51636549', '12345678', '87654321']);

// Check batch status
$status = $client->batch->status($batch['id']);

// Get results
$results = $client->batch->results($batch['id']);
```

**Error Handling**

```php
use FirmApi\Exceptions\AuthenticationException;
use FirmApi\Exceptions\RateLimitException;
use FirmApi\Exceptions\ValidationException;
use FirmApi\Exceptions\ApiException;

try {
    $company = $client->companies->byIco('51636549')->get();
} catch (AuthenticationException $e) {
    // Invalid or missing API key (401)
} catch (RateLimitException $e) {
    // Rate limit exceeded (429)
    $retryAfter = $e->getRetryAfter(); // seconds
} catch (ValidationException $e) {
    // Validation error (422)
    $errors = $e->getErrors();
} catch (ApiException $e) {
    // Other API error
    $statusCode = $e->getCode();
}
```

### All Available Methods

| Method | Description | Returns |
|---|---|---|
| `$client->companies->byIco($ico)` | Look up a company by ICO (registration number) | `CompanyQuery` |
| `$client->companies->byOrsrId($id)` | Look up a company by ORSR ID | `CompanyQuery` |
| `->withTax()->withFinancials()->...` | Chain enrichment scopes (tax, financials, insolvency, etc.) | `CompanyQuery` |
| `->withAll()` | Include all available enrichment data | `CompanyQuery` |
| `->get()` | Execute the query and return company data | `array` |
| `$client->search->byName($name)` | Search companies by name | `array` |
| `$client->search->byIco($ico)` | Search companies by partial ICO | `array` |
| `$client->search->autocomplete($q)` | Autocomplete search (Select2-compatible) | `array` |
| `$client->search->advanced([...])` | Advanced multi-field search | `array` |
| `$client->batch->byIco([...])` | Batch lookup by multiple ICOs | `array` |
| `$client->batch->byNames([...])` | Batch lookup by multiple names | `array` |
| `$client->batch->status($batchId)` | Get batch job status | `array` |
| `$client->batch->results($batchId)` | Get batch job results | `array` |
| `$client->account->usage()` | Get current period usage statistics | `array` |
| `$client->account->quota()` | Get remaining quota for current period | `array` |
| `$client->account->history($days)` | Get usage history | `array` |
| `Client::sandbox()` | Create a sandbox client for testing (no API key needed) | `Client` |

### Available Enrichment Scopes

| Method | Description |
|---|---|
| `withTax()` | Tax information (DIC, VAT number, VIES verification) |
| `withBankAccounts()` | Bank account details |
| `withFinancials()` | Financial data (revenue, profit, employees) |
| `withDebtorStatus()` | Debtor status |
| `withFinancialStatements()` | Financial statements |
| `withInsolvency()` | Insolvency records |
| `withCommercialBulletin()` | Commercial bulletin entries |
| `withPublicContracts()` | Public contracts |
| `withProcurement()` | Procurement records |
| `withExecutionAuthorizations()` | Execution authorizations |
| `withRpvs()` | Public sector partner register (RPVS) |
| `withNbs()` | NBS regulation status |
| `withTaxReliability()` | Tax reliability index |
| `withErasedVat()` | Erased VAT registrations |
| `withReges()` | PPO register of economic operators (qualified suppliers) |
| `withSocialEnterprise()` | Register of social enterprises |
| `withGleif()` | GLEIF – LEI identifier and parent company relationships |
| `withSanctions()` | EU (FSF) and US (OFAC) sanctions lists |
| `withTedTenders()` | TED – European public tenders |
| `withReplikAdministrator()` | REPLIK – bankruptcy administrators |
| `withSbs()` | Private security service (SBS) licences |
| `withTransportLicence()` | JISCD – road carrier licences |
| `withUtilityLicence()` | RONI (ÚRSO) – network industry permits |
| `withContractingAuthority()` | PPO – contracting authority status |
| `withDebarred()` | PPO – ban from public procurement |
| `withUvoReferences()` | PPO – references from public contracts |
| `withFsImports()` | Tax Authority – extended tax registers (deductions, exemptions) |
| `withIllegalEmployment()` | Labour Inspectorate – illegal employment |
| `withCourtDecisions()` | Court decisions (MS SR) |
| `withEmployerHeadcount()` | Social Insurance Agency – employer registration and headcount |
| `withSoiTravelAgency()` | SOI – travel agency register |
| `withSvpsEstablishments()` | SVPS – approved food and veterinary establishments |
| `withCrpProjects()` | Projects and subsidies from the Central Register of Projects (CRP) |
| `withTradeLicenseActivities()` | Trade-licence authorisations and business activities (ZRSR) |

## JavaScript / TypeScript SDK

Official JavaScript client for FirmAPI. Works in Node.js 18+ and modern browsers with full TypeScript support.

### Installation

```bash
npm install github:version-two/sk.firmapi.jssdk#v2.0.0
```

The SDK is not published to the npm registry yet – install it straight from GitHub, where the built package lives in dist. Pin the version with a tag so your build does not jump to a newer one.

### Quick Start

**Lookup by ICO**

```javascript
import { FirmApi } from 'firmapi';

// Create a client with your API key
const client = new FirmApi('your-api-key');

// Look up a company by ICO (base data only)
const company = await client.companies.byIco('51636549');

console.log(company.data.name);    // "Version Two s. r. o."
console.log(company.data.address); // "Bratislava ..."

// Include enrichment data with fluent methods
const detailed = await client.companies.byIco('51636549')
  .withTax()
  .withFinancials()
  .withDebtorStatus();

console.log(detailed.data.tax.dic);          // "2120733417"
console.log(detailed.data.financials?.net_turnover); // 486210

// Or get everything at once
const full = await client.companies.byIco('51636549').withAll();
```

**Configuration**

```javascript
// Full configuration
const client = new FirmApi({
  apiKey: 'your-api-key',
  timeout: 30000,             // ms (default: 30000)
  waitForFreshData: false,    // wait for a queued refresh (default: false)
  maxStaleRetries: 3,         // re-polls when waiting (default: 3)
  maxRetries: 2,              // retry transient 5xx/network (default: 2)
  sandbox: false,             // force sandbox; omit to auto-detect FIRMAPI_SANDBOX env
});

// Fast by default; opt into a completed refresh per query:
const fresh = await client.companies.byIco('51636549').fresh().get();
```

**Search**

```javascript
// Search by name
const results = await client.search.byName('Version Two');

for (const company of results.data) {
  console.log(`${company.ico} - ${company.name}`);
}

// Autocomplete (Select2-compatible)
const suggestions = await client.search.autocomplete('vers', 5);

// Advanced multi-field search
const advanced = await client.search.advanced({
  name: 'Version',
  city: 'Bratislava',
});
```

**Batch Lookup** (Requires Starter plan or higher)

```javascript
// Batch lookup by ICO
const batch = await client.batch.byIco([
  '51636549',
  '12345678',
  '87654321',
]);

// Check batch status
const status = await client.batch.status(batch.id);

// Get results when completed
const results = await client.batch.results(batch.id);
```

**Error Handling**

```javascript
import {
  FirmApi,
  AuthenticationException,
  RateLimitException,
  ValidationException,
  ApiException,
} from 'firmapi';

try {
  const company = await client.companies.byIco('51636549');
} catch (e) {
  if (e instanceof AuthenticationException) {
    // Invalid or missing API key (401)
  } else if (e instanceof RateLimitException) {
    // Rate limit exceeded (429)
    console.log(e.retryAfter); // seconds
  } else if (e instanceof ValidationException) {
    // Validation error (422)
    console.log(e.errors);
  }
}
```

### All Available Methods

| Method | Description | Returns |
|---|---|---|
| `client.companies.byIco(ico)` | Look up a company by ICO (registration number) | `CompanyQuery` |
| `client.companies.byOrsrId(id)` | Look up a company by ORSR ID | `CompanyQuery` |
| `.withTax().withFinancials()....` | Chain enrichment scopes (tax, financials, insolvency, etc.) | `CompanyQuery` |
| `.withAll()` | Include all available enrichment data | `CompanyQuery` |
| `client.search.byName(name, opts?)` | Search companies by name | `Promise<ApiResponse<CompanyData[]>>` |
| `client.search.byIco(ico, opts?)` | Search companies by partial ICO | `Promise<ApiResponse<CompanyData[]>>` |
| `client.search.autocomplete(q, limit?)` | Autocomplete search (Select2-compatible) | `Promise<AutocompleteResponse>` |
| `client.search.advanced({...})` | Advanced multi-field search | `Promise<ApiResponse<CompanyData[]>>` |
| `client.batch.byIco([...])` | Batch lookup by multiple ICOs | `Promise<BatchResponse>` |
| `client.batch.byNames([...])` | Batch lookup by multiple names | `Promise<BatchResponse>` |
| `client.batch.status(batchId)` | Get batch job status | `Promise<ApiResponse<BatchStatus>>` |
| `client.batch.results(batchId)` | Get batch job results | `Promise<BatchResponse>` |
| `client.account.usage()` | Get current period usage statistics | `Promise<UsageResponse>` |
| `client.account.quota()` | Get remaining quota for current period | `Promise<QuotaResponse>` |
| `client.account.history(days?)` | Get usage history | `Promise<HistoryResponse>` |
| `FirmApi.sandbox()` | Create a sandbox client for testing (no API key needed) | `FirmApi` |

---

Back to Documentation: https://www.firmapi.sk/en/docs.md · Pricing: https://www.firmapi.sk/en/pricing.md
