# Subjekt API — Complete LLM Reference Self-contained reference for AI coding agents and LLMs. An agent reading only this file should be able to make correct API calls, parse all responses, and handle errors. Base URL: https://api.subjekt.sk Version: v1 Auth: None required. Optional X-API-Key header (12+ char string) for higher rate limits. CORS: Access-Control-Allow-Origin: * — safe to call from browser JavaScript. --- ## 1. Endpoints Overview | Method | Path | Description | |--------|---------------------|------------------------------------------| | GET | /v1/search | Search companies by name or 8-digit ICO | | GET | /v1/entity/{ico} | Full company detail by ICO | | GET | /v1/health | API health and SK data freshness | Only GET is supported on public endpoints. POST/PUT/PATCH/DELETE return 405. --- ## 2. GET /v1/search Search companies by name or 8-digit ICO across SK and/or CZ registries. ### Parameters | Name | Type | Required | Default | Description | |---------|---------|----------|---------|---------------------------------------------------------------------| | q | string | yes | — | Company name or 8-digit ICO. Minimum 2 characters, maximum 120. | | country | string | no | both | Filter by country: sk, cz, or both. | | limit | integer | no | 10 | Results per page. Range: 1–50. | | cursor | string | no | — | Opaque pagination cursor from previous response. Expires in 15 min. | | prefer | string | no | sk | When country=both, break ties by preferring sk or cz results. | ### Response: 200 OK ```json { "results": [ { "ico": "31322832", "name": "SLOVNAFT, a.s.", "address": { "street": "Vlčie hrdlo", "building_no": "1", "city": "Bratislava", "zip": "82412", "country": "SK" }, "legal_form": "Akciová spoločnosť", "dic": "2020317949", "ic_dph": "SK2020317949", "established": "1994-01-01", "registration": { "office": "Okresný súd Bratislava I", "number": "Sa 1939/B" } } ], "count": 1, "country": "sk", "ms": 38, "next_cursor": null } ``` ### Field Descriptions | Field | Type | Nullable | Description | |-----------------|-----------------|----------|---------------------------------------------------------------------| | results | array | no | Array of SearchResult objects for the current page. | | count | integer | no | Number of results in this page (not total matches in the registry). | | country | string | no | Resolved country filter: sk, cz, or both. | | ms | integer | no | Server-side processing time in milliseconds. | | next_cursor | string | yes | Opaque cursor for the next page. Null if no more results. | ### SearchResult Fields | Field | Type | Nullable | Description | |-----------------|---------|----------|--------------------------------------------------------------------------------| | ico | string | no | 8-digit company identification number (IČO), zero-padded. | | name | string | no | Official registered name. | | address | object | no | See Address fields below. | | legal_form | string | yes | Human-readable legal form (e.g., Akciová spoločnosť). Null if not available. | | dic | string | yes | Tax identification number (DIČ). Null if not registered. | | ic_dph | string | yes | VAT registration number (IČ DPH), SK/CZ prefix + digits. Null if not a VAT payer. | | established | string | yes | Establishment date as ISO 8601 date string (YYYY-MM-DD). Null if unknown. | | registration | object | no | See Registration fields below. | ### Address Fields | Field | Type | Nullable | Description | |-------------|--------|----------|---------------------------------------------------------| | street | string | yes | Street name. Null if not available. | | building_no | string | yes | Building/house number (číslo popisné). Null if not set. | | city | string | yes | Municipality name. Null if not available. | | zip | string | yes | Postal code. Null if not available. | | country | string | no | ISO 3166-1 alpha-2 uppercase: SK or CZ. | ### Registration Fields | Field | Type | Nullable | Description | |--------|--------|----------|----------------------------------------------------| | office | string | yes | Registering court name. Null if not available. | | number | string | yes | Registration file number. Null if not available. | ### Example Request ``` curl "https://api.subjekt.sk/v1/search?q=slovnaft&country=sk&limit=5" ``` ### Rate Limits | Identity type | Limit | |--------------------|-------------| | Per identity/key | 60 req/min | | Per IP (fallback) | 30 req/min | --- ## 3. GET /v1/entity/{ico} Returns full company detail for a single 8-digit ICO. Includes all SearchResult fields plus legal_form_code, terminated, source metadata fields. ### Path Parameter | Name | Type | Required | Description | |------|--------|----------|------------------------------------| | ico | string | yes | 8-digit numeric ICO, zero-padded. | ### Query Parameter | Name | Type | Required | Default | Description | |---------|--------|----------|---------|----------------------------------------------------------| | country | string | no | — | sk or cz. If omitted, tries SK first then falls back CZ. | ### Response: 200 OK ```json { "ico": "31322832", "name": "SLOVNAFT, a.s.", "address": { "street": "Vlčie hrdlo", "building_no": "1", "city": "Bratislava", "zip": "82412", "country": "SK" }, "legal_form": "Akciová spoločnosť", "legal_form_code": "112", "dic": "2020317949", "ic_dph": "SK2020317949", "established": "1994-01-01", "terminated": null, "registration": { "office": "Okresný súd Bratislava I", "number": "Sa 1939/B" }, "source": "subjekt.sk", "updated_at": "2026-03-20T04:12:00.000Z", "source_country": "sk", "source_system": "rpo", "source_license_class": "cc_by_4_0", "source_terms_url": "https://susrrpo.docs.apiary.io/" } ``` ### Entity-Only Fields | Field | Type | Nullable | Description | |----------------------|--------|----------|-----------------------------------------------------------------------------------------------| | legal_form_code | string | yes | Numeric RPO legal form codelist code. Null for CZ entities. | | terminated | string | yes | Termination date (ISO 8601). Null if company is still active. | | source | string | no | Data source: "subjekt.sk" for SK, "ares_proxy" for CZ. | | updated_at | string | yes | ISO 8601 timestamp of the last database update for this record. | | source_country | string | no | Originating registry country: sk or cz. | | source_system | string | no | Upstream system: rpo, fs, ruz (SK systems), or ares (CZ). | | source_license_class | string | no | License: cc_by_4_0 (CC BY 4.0), cc0 (Public Domain), or ares_terms (ARES terms of service). | | source_terms_url | string | no | URL to the upstream data license or terms of service. | All SearchResult fields (ico, name, address, legal_form, dic, ic_dph, established, registration) are also present — see section 2 for their descriptions. ### Example Request ``` curl "https://api.subjekt.sk/v1/entity/31322832?country=sk" ``` ### Rate Limits | Identity type | Limit | |--------------------|--------------| | Per identity/key | 120 req/min | | Per IP (fallback) | 60 req/min | --- ## 4. GET /v1/health Returns API health and SK data freshness. No authentication, no rate limit. ### Response: 200 OK ```json { "status": "ok", "data": { "sk_entities": 752481, "sk_last_sync": "2026-03-24T03:00:12.000Z", "last_sync_status": "ok", "last_sync_entities_upserted": 412, "sync_lag_seconds": 3600, "cz_source": "ares_proxy" } } ``` ### Health Data Fields | Field | Type | Nullable | Description | |-----------------------------|---------|----------|--------------------------------------------------------------------------------------| | status | string | no | Always "ok" when the endpoint responds. | | data.sk_entities | integer | no | Total SK company records in the database. | | data.sk_last_sync | string | yes | ISO 8601 timestamp of the last completed SK batch sync. Null if no sync has run. | | data.last_sync_status | string | yes | "ok" or "error". Null if no sync has run yet. | | data.last_sync_entities_upserted | integer | no | Entities upserted during the last sync run (0 if no sync). | | data.sync_lag_seconds | integer | yes | Seconds since last sync finished. Null if no sync has run. Target: ≤ 86400 (24h). | | data.cz_source | string | no | CZ data source — always "ares_proxy" in v1 (live ARES proxy, no local caching). | ### Example Request ``` curl "https://api.subjekt.sk/v1/health" ``` --- ## 5. Error Responses All errors use the same envelope: ```json { "code": "not_found", "message": "No entity found with ICO 00000000", "request_id": "b2e3f1a0-8c4d-4e7f-a1b2-c3d4e5f60718", "details": null } ``` ### Error Codes | HTTP Status | code | When it occurs | |-------------|---------------------|-----------------------------------------------------------------| | 400 | invalid_request | Missing/invalid parameter (q too short, bad ICO format, expired cursor, etc.) | | 404 | not_found | ICO not found in SK or CZ registry. | | 405 | method_not_allowed | Non-GET method used on a public endpoint. | | 429 | rate_limited | Rate limit exceeded. Check Retry-After header for wait time. | | 500 | internal_error | Unexpected server error. | | 502 | upstream_unavailable | ARES (CZ registry) returned an error or timed out. | ### Error Fields | Field | Type | Nullable | Description | |------------|--------|----------|------------------------------------------------------| | code | string | no | Machine-readable error code (see table above). | | message | string | no | Human-readable error description. | | request_id | string | no | UUID matching the X-Request-Id response header. | | details | object | yes | Optional structured details (e.g., upstream HTTP status for 502 errors). | --- ## 6. Rate Limits Rate limiting uses a sliding 60-second window. Identity is determined by X-API-Key header (if 12+ characters) or falls back to IP address. | Endpoint | Per identity/key | Per IP (fallback) | |--------------------|------------------|-------------------| | GET /v1/search | 60 req/min | 30 req/min | | GET /v1/entity/{ico} | 120 req/min | 60 req/min | | GET /v1/health | unlimited | unlimited | When rate limited, the API returns HTTP 429 with a `Retry-After` header indicating the number of seconds to wait. --- ## 7. Response Headers All responses include: | Header | Description | |-------------------|-------------------------------------------------------------------------| | X-Request-Id | UUID assigned to the request. Present in all responses including errors.| | X-Response-Time | Server-side processing time, e.g. "42ms". | | RateLimit-Limit | Request limit for the current identity in the current window. | | RateLimit-Remaining | Requests remaining before hitting the limit. | | RateLimit-Reset | Seconds until the current rate limit window resets. | | Retry-After | Seconds to wait before retrying. Only present on 429 responses. | | Cache-Control | search: public, max-age=3600 / entity: public, max-age=86400 / health: public, max-age=60 | --- ## 8. Pagination The search endpoint is paginated using opaque cursors. - If `next_cursor` in the response is non-null, there are more results. - Pass the cursor value as the `cursor` query parameter in the next request. - Keep all other parameters (q, country, prefer, limit) identical — the cursor is tied to the exact parameter combination from the original request. - Cursors expire after 15 minutes. A 400 `invalid_request` with message "Expired cursor" is returned for stale cursors. ### JavaScript pagination example ```javascript async function* searchAll(q, country = 'sk') { let cursor = null; do { const params = new URLSearchParams({ q, country, limit: '50' }); if (cursor) params.set('cursor', cursor); const res = await fetch(`https://api.subjekt.sk/v1/search?${params}`); const data = await res.json(); yield* data.results; cursor = data.next_cursor; } while (cursor); } ``` --- ## 9. CZ Data Disclaimer Czech company data is fetched live from the Czech ARES registry (https://ares.gov.cz) and is subject to ARES terms of service. It is provided for informational purposes only and is NOT a certified legal extract. - `source_system` will be "ares" for all CZ entities. - `source_license_class` will be "ares_terms". - `source_terms_url` will be "https://ares.gov.cz/stranky/podminky-provozu". - `legal_form_code` is always null for CZ entities. - `dic` and `ic_dph` are not available for CZ entities (null). - ARES lookup adds latency (~500ms–4s). If ARES is unavailable, the API returns 502. --- ## 10. CORS Policy All responses include: ``` Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, OPTIONS Access-Control-Allow-Headers: Content-Type ``` The API can be called directly from browser JavaScript on any origin. Preflight OPTIONS requests return HTTP 204. --- ## 11. Quick Reference ```bash # Search by company name curl "https://api.subjekt.sk/v1/search?q=slovnaft&country=sk&limit=5" # Search by ICO (8-digit, zero-padded) curl "https://api.subjekt.sk/v1/search?q=31322832" # Full entity detail curl "https://api.subjekt.sk/v1/entity/31322832" # CZ entity lookup curl "https://api.subjekt.sk/v1/entity/26168685?country=cz" # Health check curl "https://api.subjekt.sk/v1/health" # With X-API-Key for higher rate limits curl -H "X-API-Key: your-key-here" "https://api.subjekt.sk/v1/search?q=tatra" ``` --- ## 12. Machine-Readable Spec OpenAPI 3.1 spec: https://subjekt.sk/openapi.yaml