{"openapi":"3.1.0","info":{"title":"KYB API — Sovereign Algerian Corporate Identity & Temporal Compliance","description":"Production API for Algerian KYB, single-identifier corporate resolution (NIF, RC, Raison Sociale), candidate discovery autocomplete, deep registry enrichment, and temporal invoice compliance under Décret exécutif 05-468 and Loi Fiscale Algérienne (Articles 169 & 176 CID, Article 30 TCA). 100% sovereign data residency in Algeria under Law 25-11.","version":"2.7.38","contact":{"name":"KYB Engineering Team","url":"https://kyb.digidevagency.dz","email":"support@digidevagency.dz"}},"servers":[{"url":"https://kyb.digidevagency.dz","description":"Production Sovereign Gateway (Algérie Télécom Datacenter, Algiers)"},{"url":"http://localhost:3001","description":"Local Development Gateway"}],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API_KEY","description":"Pass your KYB API key (e.g. `sk_live_...` or `sk_test_...`) in the Authorization header: `Bearer <token>`."},"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Pass your KYB API key (e.g. `sk_live_...` or `sk_test_...`) in the X-API-Key header."}},"schemas":{"Candidate":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"rcNumber":{"type":"string","example":"16/00-0012345B20"},"nif":{"type":"string","example":"000816097764131"},"nis":{"type":"string","example":"000816090001456"},"raisonSociale":{"type":"string","example":"CEVITAL SPA"},"raisonSocialeAr":{"type":"string","nullable":true,"example":"سيفيتال ش ذ م م"},"wilaya":{"type":"string","example":"16 - Alger"},"commune":{"type":"string","nullable":true,"example":"Kouba"},"formeJuridique":{"type":"string","example":"SPA"},"statut":{"type":"string","example":"ACTIF"},"entityType":{"type":"string","enum":["PM","PP"],"example":"PM"},"isGolden":{"type":"boolean","example":true},"source":{"type":"string","example":"cnrc"}},"required":["rcNumber","raisonSociale","statut","entityType"]},"CandidatesResponse":{"type":"object","properties":{"query":{"type":"string","example":"CEVITAL"},"count":{"type":"integer","example":2},"source":{"type":"string","enum":["cache","live","hybrid"],"example":"hybrid"},"creditsDeducted":{"type":"integer","example":1,"description":"1 credit deducted; automatically refunded if 0 candidates found."},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/Candidate"}}},"required":["query","count","candidates"]},"EnrichRequest":{"type":"object","properties":{"rc":{"type":"string","description":"Registre de Commerce number (e.g. 16/00-0012345B20 or 16000012345B20)","example":"16/00-0012345B20"},"rc_number":{"type":"string","description":"Alias for rc"},"nif":{"type":"string","description":"15 or 20-digit NIF","example":"000816097764131"},"raison_sociale":{"type":"string","description":"Corporate denomination","example":"CEVITAL AGRO INDUSTRIE"},"query":{"type":"string","description":"General lookup fallback"},"force_refresh":{"type":"boolean","default":false,"description":"Force bypass of local cache to scrape fresh CNRC registry detail"},"force_live":{"type":"boolean","default":false,"description":"Alias for force_refresh"},"poll_timeout_ms":{"type":"integer","default":40000,"description":"Maximum milliseconds to wait for synchronous paid scraper execution"}}},"EntityProfile":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"rcNumber":{"type":"string","example":"16/00-0012345B20"},"nif":{"type":"string","example":"000816097764131"},"nis":{"type":"string","nullable":true,"example":"000816090001456"},"articleImposition":{"type":"string","nullable":true,"example":"16012345678"},"raisonSociale":{"type":"string","example":"CEVITAL AGRO INDUSTRIE"},"raisonSocialeAr":{"type":"string","nullable":true,"example":"سيفيتAL"},"sigle":{"type":"string","nullable":true,"example":"CAI"},"formeJuridique":{"type":"string","example":"SPA"},"capitalSocial":{"type":"string","nullable":true,"example":"50000000000"},"adresse":{"type":"string","nullable":true,"example":"Zone Industrielle Oued Semar, Alger"},"wilaya":{"type":"string","example":"16 - Alger"},"commune":{"type":"string","nullable":true,"example":"Oued Semar"},"activitePrincipale":{"type":"string","nullable":true,"example":"Raffinage d'huiles vegetales"},"codesActivite":{"type":"array","items":{"type":"string"},"example":["104101","104102"]},"dirigeants":{"type":"array","items":{"type":"object","properties":{"nom":{"type":"string"},"qualite":{"type":"string"}}}},"isNifValid":{"type":"boolean","example":true},"statutCnrc":{"type":"string","example":"ACTIF"},"statutFiscal":{"type":"string","example":"ACTIF"},"dateImmatriculation":{"type":"string","format":"date","nullable":true},"dateRadiation":{"type":"string","format":"date","nullable":true},"isGolden":{"type":"boolean","example":true},"source":{"type":"string","example":"both"},"updatedAt":{"type":"string","format":"date-time"}},"required":["rcNumber","raisonSociale","statutCnrc"]},"EnrichResponse":{"type":"object","properties":{"status":{"type":"string","enum":["completed","cached","accepted","not_found"],"example":"completed"},"entity":{"$ref":"#/components/schemas/EntityProfile"},"creditsDeducted":{"type":"integer","example":1},"job_id":{"type":"string","nullable":true},"latencyMs":{"type":"integer","example":520}},"required":["status"]},"ComplianceInvoice":{"type":"object","properties":{"invoice_date":{"type":"string","format":"date","description":"Date of the invoice (YYYY-MM-DD)","example":"2026-03-15"},"nif":{"type":"string","description":"Supplier NIF","example":"000816097764131"},"rc":{"type":"string","description":"Supplier Registre de Commerce number","example":"16/00-0012345B20"},"article_imposition":{"type":"string","description":"Numéro d'Article d'Imposition from invoice (Secret fiscal crowd-cache ingestion)","example":"16012345678"},"amount_ttc":{"type":"number","description":"Total invoice amount including tax","example":450000}},"required":["invoice_date"]},"ComplianceVerifyRequest":{"type":"object","properties":{"invoices":{"type":"array","description":"Batch of up to 5,000 invoices for verification","items":{"$ref":"#/components/schemas/ComplianceInvoice"}},"webhook_callback":{"type":"string","format":"uri","description":"Optional webhook callback URL"}},"required":["invoices"]},"ComplianceVerifyResponse":{"type":"object","properties":{"job_id":{"type":"string","example":"job_7600fa1d-bbc3-4b5f-a430-de9cfdcb0095"},"status":{"type":"string","enum":["processing","completed"],"example":"processing"},"total_invoices":{"type":"integer","example":1},"estimated_time_seconds":{"type":"integer","example":1}},"required":["job_id","status","total_invoices"]},"BatchResolveQueryItem":{"type":"object","properties":{"id":{"type":"string","description":"Optional client correlation ID","example":"partner_1001"},"q":{"type":"string","description":"Unified query identifier (NIF, RC, or Raison Sociale)","example":"000816097764131"},"nif":{"type":"string","example":"000816097764131"},"rc":{"type":"string","example":"16/00-0012345B20"},"raison_sociale":{"type":"string","example":"CEVITAL SPA"}}},"BatchResolveRequest":{"type":"object","properties":{"queries":{"type":"array","description":"Array of 1 to 500 entity queries","items":{"$ref":"#/components/schemas/BatchResolveQueryItem"}},"force_live":{"type":"boolean","default":false,"description":"Bypass local cache"}},"required":["queries"]},"BatchResolveItemResult":{"type":"object","properties":{"id":{"type":"string","example":"partner_1001"},"query":{"type":"string","example":"000816097764131"},"resolved":{"type":"boolean","example":true},"detected_type":{"type":"string","enum":["NIF","RC","RAISON_SOCIALE"],"example":"NIF"},"error":{"type":"string","nullable":true,"example":null},"entity":{"$ref":"#/components/schemas/EntityProfile"}},"required":["query","resolved"]},"BatchResolveResponse":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/BatchResolveItemResult"}},"summary":{"type":"object","properties":{"total":{"type":"integer","example":20},"resolved":{"type":"integer","example":19},"refunded":{"type":"integer","example":1}},"required":["total","resolved","refunded"]},"source":{"type":"string","example":"batch_cache"}},"required":["results","summary"]},"ErrorResponse":{"type":"object","description":"Universal Trilingual Error Envelope returned on client or gateway errors.","properties":{"error":{"type":"string","example":"Bad Request"},"code":{"type":"string","enum":["QUERY_TOO_SHORT","INSUFFICIENT_CREDITS","RATE_LIMITED","RATE_LIMIT_EXCEEDED","MISSING_AUTHORIZATION","INVALID_API_KEY","TENANT_NOT_PROVISIONED","TENANT_SUSPENDED","REGISTRY_TIMEOUT","UPSTREAM_REGISTRY_UNAVAILABLE","VALIDATION_ERROR","INTERNAL_ERROR","INTERNAL_GATEWAY_ERROR","INVALID_NIF_FORMAT","NIF_NOT_FOUND","ENTITY_RESOLVE_FAILED","BATCH_SIZE_EXCEEDED","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_PROCESSING","FORBIDDEN_IP_WILAYA","SANDBOX_RESTRICTED"],"example":"QUERY_TOO_SHORT"},"message":{"type":"string","description":"Dynamically localized human-readable message based on Accept-Language header (defaults to French).","example":"Le terme de recherche doit comporter au moins 3 caractères."},"message_en":{"type":"string","description":"Canonical English error explanation.","example":"Search query must be at least 3 characters long."},"message_fr":{"type":"string","description":"Official French error explanation.","example":"Le terme de recherche doit comporter au moins 3 caractères."},"message_ar":{"type":"string","description":"Official Arabic error explanation.","example":"يجب أن يحتوي مصطلح البحث على 3 أحرف على الأقل."},"messages":{"type":"object","description":"Structured dictionary containing all three language variants simultaneously.","properties":{"en":{"type":"string","example":"Search query must be at least 3 characters long."},"fr":{"type":"string","example":"Le terme de recherche doit comporter au moins 3 caractères."},"ar":{"type":"string","example":"يجب أن يحتوي مصطلح البحث على 3 أحرف على الأقل."}},"required":["en","fr","ar"]},"creditsRefunded":{"type":"integer","description":"Number of credits automatically refunded to the master tenant pool (e.g. 1 on 404 or scraper error).","example":1}},"required":["error","code","message","message_en","message_fr","message_ar","messages"]}}},"paths":{"/health":{"get":{"summary":"Health Check & Sovereign Infrastructure Status","description":"Verifies connectivity to PostgreSQL and Redis, and returns the active deployment commit and version.","security":[],"responses":{"200":{"description":"Platform is fully operational","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"timestamp":{"type":"string"},"version":{"type":"string","example":"2.7.32"},"commit":{"type":"string","example":"ee59525"},"services":{"type":"object","properties":{"redis":{"type":"string","example":"up"},"postgres":{"type":"string","example":"up"}}}}}}}},"503":{"description":"Degraded state (PostgreSQL or Redis unreachable)"}}}},"/api/v1/entity/resolve":{"get":{"summary":"Single-Identifier Corporate Resolver","description":"Auto-detects identifier type (NIF with or without 00 prefix, Algerian RC number, or Raison Sociale) and returns verified identity attributes. Deducts 1 credit from master tenant pool (automatically refunded if entity is not found).","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2},"description":"15/20-digit NIF, Algerian RC number (e.g. 16B0012345), or Company Name"}],"responses":{"200":{"description":"Entity successfully resolved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityProfile"}}}},"400":{"description":"Invalid parameter (e.g. query too short)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API Key"},"402":{"description":"Insufficient credits in tenant pool"},"404":{"description":"Entity not found (1 credit automatically refunded)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/entity/resolve-batch":{"post":{"summary":"High-Throughput Batch Corporate Resolver","description":"Resolves up to 500 corporate entities (NIF, RC, Raison Sociale) in a single optimized database query. Deducts 1 credit per query item; credits for unresolvable entries are automatically refunded.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResolveRequest"}}}},"responses":{"200":{"description":"Batch resolution result with individual item statuses and refund summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResolveResponse"}}}},"400":{"description":"Validation error or batch size exceeded (> 500)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient credits in tenant pool","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Upstream government registry unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/entity/candidates":{"get":{"summary":"Candidate Autocomplete Discovery (Stage 1)","description":"Fast autocomplete discovery returning matching corporate candidates. Optimized for Personnes Morales (PM / Sociétés) by name, while Personnes Physiques (PP) are resolved deterministically via RC (Category A/C) or NIF (ADR #118). Queries local PostgreSQL cache first, followed by live CNRC protected registry search if needed. Discovered candidates are immediately upserted into local PostgreSQL database. Deducts 1 credit (automatically refunded if 0 candidates found).","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":3},"description":"Company name, acronym, or RC prefix (minimum 3 characters)"},{"name":"searchMode","in":"query","required":false,"schema":{"type":"string","enum":["pm","pp","both"],"default":"pm"},"description":"Filter by Personne Morale (PM / Société, default), Personne Physique (PP / Artisan), or both. Under ADR #118, name discovery targets PM corporate entities; PP entities require deterministic RC or NIF."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"minimum":1,"maximum":50},"description":"Maximum number of candidate rows to return (1 to 50, default 10). Live CNRC returns up to 10 entities per page (native Liferay delta); cached results return up to 50 entities."},{"name":"live","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Force querying live CNRC free account pool"}],"responses":{"200":{"description":"Candidates successfully retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidatesResponse"}}}},"400":{"description":"Query too short (min 4 characters required)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API Key"},"402":{"description":"Insufficient credits in tenant pool"}}}},"/api/v1/entity/enrich":{"post":{"summary":"Targeted Deep Detail Enrichment (Stage 2)","description":"On-demand deep KYB corporate registry enrichment. Acquires high-assurance verified registry session lease, parses multi-tab registry details (share capital, registered office, NAE activity codes, legal representatives, NIS), and validates fiscal status with the Ministry of Finance (DGI). Deducts 1 credit (automatically refunded on timeout or failure).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichRequest"}}}},"responses":{"200":{"description":"Enriched Golden profile successfully retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichResponse"}}}},"400":{"description":"Missing parameters (RC or NIF required)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API Key"},"402":{"description":"Insufficient credits in tenant pool"},"502":{"description":"Scraper failure (1 credit automatically refunded)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/compliance/verify":{"post":{"summary":"Invoice Temporal Compliance Verification","description":"Verifies vendor legal existence and active tax status as of the specific invoice date under Algerian Law (Articles 169 & 176 CID & Article 30 TCA). Prevents fiscal penalties and expense disallowance from struck-off (radié) entities. Automatically crowd-caches Article d'Imposition. Deducts 1 credit.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceVerifyRequest"}}}},"responses":{"200":{"description":"Compliance verdict successfully computed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceVerifyResponse"}}}},"400":{"description":"Invalid payload or date format"},"401":{"description":"Missing or invalid API Key"},"402":{"description":"Insufficient credits in tenant pool"}}}},"/api/v1/keys":{"get":{"summary":"List Tenant API Sub-Keys","description":"Returns all provisioned API sub-keys for the authenticated master tenant.","responses":{"200":{"description":"Array of API sub-keys with rate limits and IP whitelist configuration"},"401":{"description":"Unauthorized"}}},"post":{"summary":"Provision Scoped API Sub-Key","description":"Creates a new API sub-key with optional CIDR/IP restrictions and quota ceiling.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","example":"ERP Integration Prod"},"quotaCeiling":{"type":"integer","example":5000},"isSandbox":{"type":"boolean","default":false,"example":false},"allowedIps":{"type":"array","items":{"type":"string"},"example":["197.112.0.0/16","105.100.1.5"]}},"required":["label","quotaCeiling"]}}}},"responses":{"201":{"description":"Key created. Secret token is shown ONLY ONCE upon creation.","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","example":"cf_live_abc123..."},"id":{"type":"string","format":"uuid"},"label":{"type":"string"},"status":{"type":"string","example":"active"},"quotaCeiling":{"type":"integer","example":5000}}}}}}}}},"/api/v1/ledger/events":{"get":{"summary":"Tenant Ledger Audit Events","description":"Returns cryptographically verifiable ledger entries (refills, charges, refunds, resets) for the authenticated tenant account.","responses":{"200":{"description":"Array of ledger bookkeeping entries","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["charge","refund","refill","monthly_reset","grace_period"]},"amount":{"type":"integer"},"balanceAfter":{"type":"integer"},"endpoint":{"type":"string","nullable":true},"nifQueried":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"subKeyLabel":{"type":"string","nullable":true}}}}}}},"401":{"description":"Unauthorized"}}}},"/api/v1/ledger/requests":{"get":{"summary":"Tenant API Request Explorer","description":"Returns recent metered queries (charges and refunds) with HTTP status and queried identifier.","responses":{"200":{"description":"Recent metered API requests with status","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["charge","refund"]},"amount":{"type":"integer"},"balanceAfter":{"type":"integer"},"endpoint":{"type":"string"},"nifQueried":{"type":"string","nullable":true},"httpStatus":{"type":"integer","nullable":true},"createdAt":{"type":"string","format":"date-time"},"subKeyLabel":{"type":"string","nullable":true}}}}}}},"401":{"description":"Unauthorized"}}}},"/api/v1/billing/overview":{"get":{"summary":"Master Pool Balance & Consumption Overview","description":"Returns real-time master pool credit balance, cap, active key count, and 14-day daily consumption chart data.","responses":{"200":{"description":"Billing overview and consumption metrics","content":{"application/json":{"schema":{"type":"object","properties":{"masterPool":{"type":"object","properties":{"balance":{"type":"integer","example":9482},"cap":{"type":"integer","example":50000},"status":{"type":"string","example":"active"}}},"activeKeysCount":{"type":"integer","example":3},"dailyConsumption":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","example":"07 oct."},"value":{"type":"integer","example":142}}}},"hasNoUsage":{"type":"boolean","example":false}}}}}},"401":{"description":"Unauthorized"}}}}}}