// Kuvola Institutional Data API — TypeScript starter (no npm package published; copy this file) const BASE_URL = "https://kuvola.ao"; export class KuvolaClient { constructor(private apiKey: string) {} private async request(path: string, params: Record = {}): Promise { const url = new URL(BASE_URL + path); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); const res = await fetch(url, { headers: { Authorization: `Bearer ${this.apiKey}` } }); // Rate limits: every response carries X-RateLimit-Limit / -Remaining. if (res.status === 429) throw new Error(`Rate limited. Retry after: ${res.headers.get("X-RateLimit-Reset")}`); if (!res.ok) { const body = await res.json().catch(() => null); throw new Error(`Kuvola API error ${res.status}: ${body?.error?.message ?? res.statusText}`); } return res.json(); } // Pagination: pass page/pageSize; response.pagination has totalPages. async v2ListMarkets(params: Record = {}) { return this.request("/api/v2/markets", params); } } // Usage: // const client = new KuvolaClient("kv_live_..."); // const { data, pagination } = await client.v2ListMarkets({ pageSize: "25" });