@baziapi/sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,895 @@
1
+ # @baziapi/sdk
2
+
3
+ [![npm version](https://badge.fury.io/js/%40baziapi%2Fsdk.svg)](https://www.npmjs.com/package/@baziapi/sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue)](https://www.typescriptlang.org/)
6
+
7
+ **Official TypeScript SDK for the BaZi API.**
8
+
9
+ Calculate [BaZi (Four Pillars of Destiny)](https://en.wikipedia.org/wiki/Four_Pillars_of_Destiny) with a type-safe, framework-agnostic client that works in Node.js, Bun, Deno, the browser, and Edge runtimes.
10
+
11
+ ---
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ # npm
17
+ npm install @baziapi/sdk
18
+
19
+ # pnpm
20
+ pnpm add @baziapi/sdk
21
+
22
+ # yarn
23
+ yarn add @baziapi/sdk
24
+
25
+ # bun
26
+ bun add @baziapi/sdk
27
+ ```
28
+
29
+ > **Node.js**: Requires Node ≥ 18.0.0 (native fetch). For Node < 18, add a `fetch` polyfill (e.g. `node-fetch`).
30
+
31
+ ---
32
+
33
+ ## Quick Start
34
+
35
+ ```typescript
36
+ import { BaziClient } from '@baziapi/sdk';
37
+
38
+ const client = new BaziClient({ apiKey: 'bazi_xxxx' });
39
+
40
+ const result = await client.bazi.calculate({
41
+ birthDate: '1998-08-12', // Format: YYYY-MM-DD (Year-Month-Day)
42
+ birthTime: '10:30', // Format: HH:mm (24-hour clock)
43
+ gender: 'male',
44
+ timezone: 'Asia/Dhaka',
45
+ language: 'en',
46
+ });
47
+
48
+ console.log(result.pillars);
49
+ // { yearPillar: '戊寅', monthPillar: '庚申', dayPillar: '庚申', hourPillar: '戊午' }
50
+
51
+ console.log(result.analysis?.dayMasterStrength); // 'Strong' | 'Weak'
52
+ console.log(result.luckPillars?.pillars); // 10-year luck cycles
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Client Configuration
58
+
59
+ ```typescript
60
+ const client = new BaziClient({
61
+ apiKey: 'bazi_xxxx', // Your BaZi API key
62
+ baseUrl: 'https://api.bazi.dev', // API base URL (default: production)
63
+ timeout: 10_000, // Request timeout in ms (default: 10s)
64
+ retries: 3, // Retry attempts for transient errors (default: 3)
65
+ retryDelay: 500, // Base retry delay in ms, exponential (default: 500ms)
66
+ onError: (err) => console.error(err), // Optional error callback for monitoring
67
+ });
68
+ ```
69
+
70
+ ---
71
+
72
+ ## API Reference
73
+
74
+ ### `client.bazi`
75
+
76
+ | Method | Description |
77
+ | ------------------ | ---------------------------------------------- |
78
+ | `calculate(input)` | Calculate BaZi for a given birth date and time |
79
+
80
+ ## Error Handling
81
+
82
+ All SDK errors extend `BaziError`. Use `instanceof` checks for precise handling.
83
+
84
+ ```typescript
85
+ import { BaziClient, ApiError, ValidationError, TimeoutError, NetworkError } from '@baziapi/sdk';
86
+
87
+ try {
88
+ const result = await client.bazi.calculate({ ... });
89
+ } catch (error) {
90
+ if (error instanceof ValidationError) {
91
+ // Input failed client-side validation — no network request was made
92
+ console.error(`Field '${error.field}': ${error.message}`);
93
+ } else if (error instanceof ApiError) {
94
+ // Server returned a non-2xx response
95
+ console.error(`HTTP ${error.statusCode}: ${error.message}`);
96
+ console.error('Request ID:', error.requestId);
97
+ console.error('Server errors:', error.errors);
98
+ } else if (error instanceof TimeoutError) {
99
+ console.error(`Timed out after ${error.timeoutMs}ms`);
100
+ } else if (error instanceof NetworkError) {
101
+ console.error('No network connection:', error.cause);
102
+ }
103
+ }
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Retry Behaviour
109
+
110
+ The SDK automatically retries on transient failures using exponential backoff.
111
+
112
+ | Condition | Retried? |
113
+ | ----------------------------- | -------------------------------------- |
114
+ | Network failure (no internet) | ✅ Yes |
115
+ | `429 Too Many Requests` | ✅ Yes (respects `Retry-After` header) |
116
+ | `500 / 502 / 503 / 504` | ✅ Yes |
117
+ | `400 Bad Request` | ❌ No |
118
+ | `401 Unauthorized` | ❌ No |
119
+ | `403 Forbidden` | ❌ No |
120
+ | `404 Not Found` | ❌ No |
121
+ | `409 Conflict` | ❌ No |
122
+ | `422 Unprocessable Entity` | ❌ No |
123
+
124
+ Backoff formula: `retryDelay * 2^attemptIndex`
125
+
126
+ Default: up to **3 retries** with **500ms base delay** (max ~3.5s total wait).
127
+
128
+ ---
129
+
130
+ ## TypeScript Support
131
+
132
+ The SDK ships with full TypeScript declarations. All types are derived directly from the backend source of truth.
133
+
134
+ ```typescript
135
+ import type {
136
+ BaziCalculateRequest,
137
+ BaziCalculateResponse,
138
+ FourPillars,
139
+ Analysis,
140
+ LuckPillars,
141
+ } from '@baziapi/sdk';
142
+ ```
143
+
144
+ ---
145
+
146
+ ## Runtime Compatibility
147
+
148
+ | Runtime | Version | Notes |
149
+ | ------------ | ---------- | ------------------------------- |
150
+ | Node.js | ≥ 18.0.0 | Native fetch available |
151
+ | Bun | ≥ 1.0.0 | Fully supported |
152
+ | Deno | ≥ 1.28.0 | `npm:@baziapi/sdk` |
153
+ | Browser | Chrome 90+ | Via CDN or bundler |
154
+ | Edge Runtime | Latest | Cloudflare Workers, Vercel Edge |
155
+
156
+ ---
157
+
158
+ ## Browser / CDN Usage
159
+
160
+ ```html
161
+ <script type="module">
162
+ import { BaziClient } from 'https://cdn.jsdelivr.net/npm/@baziapi/sdk/dist/index.mjs';
163
+
164
+ const client = new BaziClient({ apiKey: 'bazi_xxxx' });
165
+ const result = await client.bazi.calculate({
166
+ birthDate: '1998-08-12',
167
+ gender: 'male',
168
+ });
169
+ </script>
170
+ ```
171
+
172
+ > **⚠️ Security:** Never expose API keys in client-side browser code in production.
173
+ > Use a backend proxy to make BaZi API calls on behalf of users.
174
+
175
+ For CSP-compliant usage, add the API domain to your `connect-src` directive:
176
+
177
+ ```
178
+ Content-Security-Policy: connect-src 'self' https://api.bazi.dev;
179
+ ```
180
+
181
+ ---
182
+
183
+ ## Examples
184
+
185
+ - [`examples/node-esm/`](./examples/node-esm/) — Node.js ESM
186
+ - [`examples/node-cjs/`](./examples/node-cjs/) — Node.js CommonJS
187
+ - [`examples/bun/`](./examples/bun/) — Bun
188
+ - [`examples/next-js/`](./examples/next-js/) — Next.js App Router (Server Component)
189
+ - [`examples/browser/`](./examples/browser/) — Browser / CDN
190
+
191
+ ---
192
+
193
+ ## Integration Guide
194
+
195
+ The SDK works across every major JavaScript runtime and framework. Pick your platform below.
196
+
197
+ ---
198
+
199
+ ### 🟢 Node.js
200
+
201
+ **Install:**
202
+
203
+ ```bash
204
+ npm install @baziapi/sdk
205
+ ```
206
+
207
+ **ESM (recommended):**
208
+
209
+ ```typescript
210
+ // index.mjs
211
+ import { BaziClient } from '@baziapi/sdk';
212
+
213
+ const client = new BaziClient({ apiKey: process.env.BAZI_API_KEY! });
214
+
215
+ const result = await client.bazi.calculate({
216
+ birthDate: '1998-08-12',
217
+ birthTime: '10:30',
218
+ gender: 'male',
219
+ timezone: 'Asia/Dhaka',
220
+ language: 'en',
221
+ });
222
+
223
+ console.log(result.pillars);
224
+ ```
225
+
226
+ **CommonJS:**
227
+
228
+ ```javascript
229
+ // index.cjs
230
+ const { BaziClient } = require('@baziapi/sdk');
231
+
232
+ const client = new BaziClient({ apiKey: process.env.BAZI_API_KEY });
233
+
234
+ client.bazi
235
+ .calculate({
236
+ birthDate: '1998-08-12',
237
+ birthTime: '10:30',
238
+ gender: 'male',
239
+ timezone: 'Asia/Dhaka',
240
+ })
241
+ .then((result) => console.log(result.pillars));
242
+ ```
243
+
244
+ > Requires **Node.js ≥ 18.0.0** (native `fetch`). For older Node, install a fetch polyfill like `node-fetch`.
245
+
246
+ ---
247
+
248
+ ### 🟣 Bun
249
+
250
+ **Install:**
251
+
252
+ ```bash
253
+ bun add @baziapi/sdk
254
+ ```
255
+
256
+ ```typescript
257
+ // index.ts
258
+ import { BaziClient } from '@baziapi/sdk';
259
+
260
+ const client = new BaziClient({
261
+ apiKey: Bun.env.BAZI_API_KEY ?? '',
262
+ });
263
+
264
+ const result = await client.bazi.calculate({
265
+ birthDate: '1998-08-12',
266
+ birthTime: '10:30',
267
+ gender: 'male',
268
+ timezone: 'Asia/Dhaka',
269
+ language: 'en',
270
+ });
271
+
272
+ console.log(result.pillars);
273
+ ```
274
+
275
+ ```bash
276
+ bun run index.ts
277
+ ```
278
+
279
+ ---
280
+
281
+ ### 🦕 Deno
282
+
283
+ No install needed — import directly via npm specifier:
284
+
285
+ ```typescript
286
+ // main.ts
287
+ import { BaziClient } from 'npm:@baziapi/sdk';
288
+
289
+ const client = new BaziClient({
290
+ apiKey: Deno.env.get('BAZI_API_KEY') ?? '',
291
+ });
292
+
293
+ const result = await client.bazi.calculate({
294
+ birthDate: '1998-08-12',
295
+ birthTime: '10:30',
296
+ gender: 'male',
297
+ timezone: 'Asia/Dhaka',
298
+ language: 'en',
299
+ });
300
+
301
+ console.log(result.pillars);
302
+ ```
303
+
304
+ ```bash
305
+ deno run --allow-net --allow-env main.ts
306
+ ```
307
+
308
+ ---
309
+
310
+ ### ▲ Next.js (App Router)
311
+
312
+ **Install:**
313
+
314
+ ```bash
315
+ npm install @baziapi/sdk
316
+ ```
317
+
318
+ **Server Component** (recommended — API key is safe):
319
+
320
+ ```typescript
321
+ // app/bazi/page.tsx
322
+ import { BaziClient } from '@baziapi/sdk';
323
+
324
+ const client = new BaziClient({ apiKey: process.env.BAZI_API_KEY! });
325
+
326
+ export default async function BaziPage() {
327
+ const result = await client.bazi.calculate({
328
+ birthDate: '1998-08-12',
329
+ birthTime: '10:30',
330
+ gender: 'male',
331
+ timezone: 'Asia/Dhaka',
332
+ language: 'en',
333
+ });
334
+
335
+ return (
336
+ <main>
337
+ <h1>BaZi Chart</h1>
338
+ <pre>{JSON.stringify(result.pillars, null, 2)}</pre>
339
+ </main>
340
+ );
341
+ }
342
+ ```
343
+
344
+ **API Route** (for client-side fetch):
345
+
346
+ ```typescript
347
+ // app/api/bazi/route.ts
348
+ import { BaziClient } from '@baziapi/sdk';
349
+ import { NextRequest, NextResponse } from 'next/server';
350
+
351
+ const client = new BaziClient({ apiKey: process.env.BAZI_API_KEY! });
352
+
353
+ export async function POST(req: NextRequest) {
354
+ const body = await req.json();
355
+
356
+ const result = await client.bazi.calculate({
357
+ birthDate: body.birthDate,
358
+ birthTime: body.birthTime,
359
+ gender: body.gender,
360
+ timezone: body.timezone ?? 'Asia/Shanghai',
361
+ language: body.language ?? 'en',
362
+ });
363
+
364
+ return NextResponse.json(result);
365
+ }
366
+ ```
367
+
368
+ **`.env.local`:**
369
+
370
+ ```
371
+ BAZI_API_KEY=bazi_xxxx
372
+ ```
373
+
374
+ ---
375
+
376
+ ### 💿 Remix
377
+
378
+ ```typescript
379
+ // app/routes/bazi.tsx
380
+ import { json, type LoaderFunctionArgs } from '@remix-run/node';
381
+ import { useLoaderData } from '@remix-run/react';
382
+ import { BaziClient } from '@baziapi/sdk';
383
+
384
+ const client = new BaziClient({ apiKey: process.env.BAZI_API_KEY! });
385
+
386
+ export async function loader({ request }: LoaderFunctionArgs) {
387
+ const result = await client.bazi.calculate({
388
+ birthDate: '1998-08-12',
389
+ birthTime: '10:30',
390
+ gender: 'male',
391
+ timezone: 'Asia/Dhaka',
392
+ language: 'en',
393
+ });
394
+
395
+ return json(result);
396
+ }
397
+
398
+ export default function BaziRoute() {
399
+ const data = useLoaderData<typeof loader>();
400
+ return <pre>{JSON.stringify(data.pillars, null, 2)}</pre>;
401
+ }
402
+ ```
403
+
404
+ ---
405
+
406
+ ### 🚀 Astro
407
+
408
+ ```typescript
409
+ // src/pages/api/bazi.ts
410
+ import type { APIRoute } from 'astro';
411
+ import { BaziClient } from '@baziapi/sdk';
412
+
413
+ const client = new BaziClient({ apiKey: import.meta.env.BAZI_API_KEY });
414
+
415
+ export const POST: APIRoute = async ({ request }) => {
416
+ const body = await request.json();
417
+
418
+ const result = await client.bazi.calculate({
419
+ birthDate: body.birthDate,
420
+ birthTime: body.birthTime,
421
+ gender: body.gender,
422
+ timezone: body.timezone ?? 'Asia/Shanghai',
423
+ language: body.language ?? 'en',
424
+ });
425
+
426
+ return new Response(JSON.stringify(result), {
427
+ headers: { 'Content-Type': 'application/json' },
428
+ });
429
+ };
430
+ ```
431
+
432
+ **`astro.config.mjs`** — enable SSR:
433
+
434
+ ```js
435
+ export default defineConfig({ output: 'server' });
436
+ ```
437
+
438
+ ---
439
+
440
+ ### 🔥 SvelteKit
441
+
442
+ ```typescript
443
+ // src/routes/api/bazi/+server.ts
444
+ import { json } from '@sveltejs/kit';
445
+ import { BaziClient } from '@baziapi/sdk';
446
+ import { BAZI_API_KEY } from '$env/static/private';
447
+
448
+ const client = new BaziClient({ apiKey: BAZI_API_KEY });
449
+
450
+ export async function POST({ request }) {
451
+ const body = await request.json();
452
+
453
+ const result = await client.bazi.calculate({
454
+ birthDate: body.birthDate,
455
+ birthTime: body.birthTime,
456
+ gender: body.gender,
457
+ timezone: body.timezone ?? 'Asia/Shanghai',
458
+ language: body.language ?? 'en',
459
+ });
460
+
461
+ return json(result);
462
+ }
463
+ ```
464
+
465
+ ---
466
+
467
+ ### 🐈 NestJS
468
+
469
+ **Install:**
470
+
471
+ ```bash
472
+ npm install @baziapi/sdk
473
+ ```
474
+
475
+ **Service:**
476
+
477
+ ```typescript
478
+ // bazi/bazi.service.ts
479
+ import { Injectable } from '@nestjs/common';
480
+ import { BaziClient } from '@baziapi/sdk';
481
+ import { ConfigService } from '@nestjs/config';
482
+
483
+ @Injectable()
484
+ export class BaziService {
485
+ private readonly client: BaziClient;
486
+
487
+ constructor(private readonly config: ConfigService) {
488
+ this.client = new BaziClient({
489
+ apiKey: this.config.get<string>('BAZI_API_KEY')!,
490
+ });
491
+ }
492
+
493
+ async calculate(birthDate: string, birthTime: string, gender: 'male' | 'female') {
494
+ return this.client.bazi.calculate({ birthDate, birthTime, gender });
495
+ }
496
+ }
497
+ ```
498
+
499
+ **Controller:**
500
+
501
+ ```typescript
502
+ // bazi/bazi.controller.ts
503
+ import { Controller, Post, Body } from '@nestjs/common';
504
+ import { BaziService } from './bazi.service';
505
+
506
+ @Controller('bazi')
507
+ export class BaziController {
508
+ constructor(private readonly baziService: BaziService) {}
509
+
510
+ @Post('calculate')
511
+ calculate(@Body() body: { birthDate: string; birthTime: string; gender: 'male' | 'female' }) {
512
+ return this.baziService.calculate(body.birthDate, body.birthTime, body.gender);
513
+ }
514
+ }
515
+ ```
516
+
517
+ ---
518
+
519
+ ### ⚡ Express / Fastify
520
+
521
+ **Express:**
522
+
523
+ ```typescript
524
+ import express from 'express';
525
+ import { BaziClient } from '@baziapi/sdk';
526
+
527
+ const app = express();
528
+ app.use(express.json());
529
+
530
+ const client = new BaziClient({ apiKey: process.env.BAZI_API_KEY! });
531
+
532
+ app.post('/bazi/calculate', async (req, res) => {
533
+ const result = await client.bazi.calculate(req.body);
534
+ res.json(result);
535
+ });
536
+
537
+ app.listen(3000);
538
+ ```
539
+
540
+ **Fastify:**
541
+
542
+ ```typescript
543
+ import Fastify from 'fastify';
544
+ import { BaziClient } from '@baziapi/sdk';
545
+
546
+ const app = Fastify();
547
+ const client = new BaziClient({ apiKey: process.env.BAZI_API_KEY! });
548
+
549
+ app.post('/bazi/calculate', async (request) => {
550
+ return client.bazi.calculate(request.body as any);
551
+ });
552
+
553
+ app.listen({ port: 3000 });
554
+ ```
555
+
556
+ ---
557
+
558
+ ### ▲ Vercel Functions
559
+
560
+ ```typescript
561
+ // api/bazi.ts
562
+ import type { VercelRequest, VercelResponse } from '@vercel/node';
563
+ import { BaziClient } from '@baziapi/sdk';
564
+
565
+ const client = new BaziClient({ apiKey: process.env.BAZI_API_KEY! });
566
+
567
+ export default async function handler(req: VercelRequest, res: VercelResponse) {
568
+ if (req.method !== 'POST') return res.status(405).json({ error: 'Method Not Allowed' });
569
+
570
+ const result = await client.bazi.calculate(req.body);
571
+ res.json(result);
572
+ }
573
+ ```
574
+
575
+ **`vercel.json`:**
576
+
577
+ ```json
578
+ {
579
+ "functions": {
580
+ "api/bazi.ts": { "memory": 256, "maxDuration": 10 }
581
+ }
582
+ }
583
+ ```
584
+
585
+ ---
586
+
587
+ ### 🌐 Netlify Functions
588
+
589
+ ```typescript
590
+ // netlify/functions/bazi.ts
591
+ import type { Handler } from '@netlify/functions';
592
+ import { BaziClient } from '@baziapi/sdk';
593
+
594
+ const client = new BaziClient({ apiKey: process.env.BAZI_API_KEY! });
595
+
596
+ export const handler: Handler = async (event) => {
597
+ if (event.httpMethod !== 'POST') {
598
+ return { statusCode: 405, body: 'Method Not Allowed' };
599
+ }
600
+
601
+ const body = JSON.parse(event.body ?? '{}');
602
+ const result = await client.bazi.calculate(body);
603
+
604
+ return {
605
+ statusCode: 200,
606
+ headers: { 'Content-Type': 'application/json' },
607
+ body: JSON.stringify(result),
608
+ };
609
+ };
610
+ ```
611
+
612
+ ---
613
+
614
+ ### ☁️ Cloudflare Workers
615
+
616
+ ```typescript
617
+ // src/index.ts
618
+ import { BaziClient } from '@baziapi/sdk';
619
+
620
+ export interface Env {
621
+ BAZI_API_KEY: string;
622
+ }
623
+
624
+ export default {
625
+ async fetch(request: Request, env: Env): Promise<Response> {
626
+ if (request.method !== 'POST') {
627
+ return new Response('Method Not Allowed', { status: 405 });
628
+ }
629
+
630
+ const client = new BaziClient({ apiKey: env.BAZI_API_KEY });
631
+ const body = await request.json<any>();
632
+ const result = await client.bazi.calculate(body);
633
+
634
+ return new Response(JSON.stringify(result), {
635
+ headers: { 'Content-Type': 'application/json' },
636
+ });
637
+ },
638
+ };
639
+ ```
640
+
641
+ **`wrangler.toml`:**
642
+
643
+ ```toml
644
+ name = "bazi-worker"
645
+ main = "src/index.ts"
646
+ compatibility_date = "2024-01-01"
647
+
648
+ [vars]
649
+ BAZI_API_KEY = "bazi_xxxx"
650
+ ```
651
+
652
+ ---
653
+
654
+ ### 🟡 AWS Lambda (Node.js)
655
+
656
+ ```typescript
657
+ // handler.ts
658
+ import { APIGatewayProxyHandler } from 'aws-lambda';
659
+ import { BaziClient } from '@baziapi/sdk';
660
+
661
+ const client = new BaziClient({ apiKey: process.env.BAZI_API_KEY! });
662
+
663
+ export const calculate: APIGatewayProxyHandler = async (event) => {
664
+ const body = JSON.parse(event.body ?? '{}');
665
+ const result = await client.bazi.calculate(body);
666
+
667
+ return {
668
+ statusCode: 200,
669
+ headers: { 'Content-Type': 'application/json' },
670
+ body: JSON.stringify(result),
671
+ };
672
+ };
673
+ ```
674
+
675
+ **`serverless.yml`:**
676
+
677
+ ```yaml
678
+ functions:
679
+ calculate:
680
+ handler: handler.calculate
681
+ events:
682
+ - httpApi:
683
+ path: /bazi/calculate
684
+ method: post
685
+ environment:
686
+ BAZI_API_KEY: ${env:BAZI_API_KEY}
687
+ ```
688
+
689
+ ---
690
+
691
+ ### 🔀 No-Code & Automation Platforms
692
+
693
+ > These platforms consume the BaZi API via **HTTP requests** — no npm install required.
694
+ > For platforms that support JavaScript code nodes, you can also install and use the SDK directly.
695
+
696
+ #### n8n
697
+
698
+ **Option A — HTTP Request Node** (simplest):
699
+
700
+ | Field | Value |
701
+ | ------------------ | ----------------------------------------------- |
702
+ | **Method** | `POST` |
703
+ | **URL** | `https://api.bazi.dev/api/v1/bazi/calculate` |
704
+ | **Authentication** | Header Auth → `Authorization: Bearer bazi_xxxx` |
705
+ | **Content-Type** | `application/json` |
706
+
707
+ **Body:**
708
+
709
+ ```json
710
+ {
711
+ "birthDate": "{{ $json.birthDate }}",
712
+ "birthTime": "{{ $json.birthTime }}",
713
+ "gender": "{{ $json.gender }}",
714
+ "timezone": "Asia/Dhaka",
715
+ "language": "en"
716
+ }
717
+ ```
718
+
719
+ **Option B — Code Node** (full SDK, dynamic logic):
720
+
721
+ ```javascript
722
+ // n8n Code Node (Node.js mode)
723
+ const { BaziClient } = require('@baziapi/sdk');
724
+
725
+ const client = new BaziClient({ apiKey: $env.BAZI_API_KEY });
726
+
727
+ const result = await client.bazi.calculate({
728
+ birthDate: $input.first().json.birthDate,
729
+ birthTime: $input.first().json.birthTime,
730
+ gender: $input.first().json.gender,
731
+ timezone: 'Asia/Dhaka',
732
+ language: 'en',
733
+ });
734
+
735
+ return [{ json: result }];
736
+ ```
737
+
738
+ ---
739
+
740
+ #### Zapier
741
+
742
+ **Option A — Webhooks by Zapier → POST**:
743
+
744
+ | Field | Value |
745
+ | ---------------- | -------------------------------------------- |
746
+ | **URL** | `https://api.bazi.dev/api/v1/bazi/calculate` |
747
+ | **Payload Type** | `JSON` |
748
+ | **Headers** | `Authorization: Bearer bazi_xxxx` |
749
+
750
+ **Data:**
751
+
752
+ ```json
753
+ {
754
+ "birthDate": "1998-08-12",
755
+ "birthTime": "10:30",
756
+ "gender": "male",
757
+ "timezone": "Asia/Dhaka",
758
+ "language": "en"
759
+ }
760
+ ```
761
+
762
+ **Option B — Code by Zapier** (Node.js, full SDK):
763
+
764
+ ```javascript
765
+ const { BaziClient } = require('@baziapi/sdk');
766
+
767
+ const client = new BaziClient({ apiKey: process.env.BAZI_API_KEY });
768
+
769
+ const result = await client.bazi.calculate({
770
+ birthDate: inputData.birthDate,
771
+ birthTime: inputData.birthTime,
772
+ gender: inputData.gender,
773
+ timezone: 'Asia/Dhaka',
774
+ language: 'en',
775
+ });
776
+
777
+ output = { result };
778
+ ```
779
+
780
+ ---
781
+
782
+ #### Pipedream
783
+
784
+ Pipedream runs Node.js natively — install and use the SDK directly:
785
+
786
+ ```javascript
787
+ // Pipedream Step (Node.js)
788
+ import { BaziClient } from '@baziapi/sdk';
789
+
790
+ export default defineComponent({
791
+ props: {
792
+ bazi_api_key: { type: 'string', secret: true },
793
+ },
794
+ async run({ steps, $ }) {
795
+ const client = new BaziClient({ apiKey: this.bazi_api_key });
796
+
797
+ const result = await client.bazi.calculate({
798
+ birthDate: steps.trigger.event.birthDate,
799
+ birthTime: steps.trigger.event.birthTime,
800
+ gender: steps.trigger.event.gender,
801
+ timezone: 'Asia/Dhaka',
802
+ language: 'en',
803
+ });
804
+
805
+ return result;
806
+ },
807
+ });
808
+ ```
809
+
810
+ ---
811
+
812
+ #### Make (Integromat)
813
+
814
+ Use **HTTP → Make a request** module:
815
+
816
+ | Field | Value |
817
+ | ------------- | -------------------------------------------- |
818
+ | **URL** | `https://api.bazi.dev/api/v1/bazi/calculate` |
819
+ | **Method** | `POST` |
820
+ | **Headers** | `Authorization: Bearer bazi_xxxx` |
821
+ | **Body type** | `Raw` → `application/json` |
822
+
823
+ **Body:**
824
+
825
+ ```json
826
+ {
827
+ "birthDate": "{{birthDate}}",
828
+ "birthTime": "{{birthTime}}",
829
+ "gender": "{{gender}}",
830
+ "timezone": "Asia/Dhaka",
831
+ "language": "en"
832
+ }
833
+ ```
834
+
835
+ ---
836
+
837
+ #### cURL (Testing / CI)
838
+
839
+ ```bash
840
+ curl -X POST https://api.bazi.dev/api/v1/bazi/calculate \
841
+ -H "Authorization: Bearer bazi_xxxx" \
842
+ -H "Content-Type: application/json" \
843
+ -d '{
844
+ "birthDate": "1998-08-12",
845
+ "birthTime": "10:30",
846
+ "gender": "male",
847
+ "timezone": "Asia/Dhaka",
848
+ "language": "en"
849
+ }'
850
+ ```
851
+
852
+ ---
853
+
854
+ ## Pricing & API Keys
855
+
856
+ To use this SDK in production, you need an active API Key from our platform. We offer flexible plans tailored to your business needs.
857
+
858
+ > All plans include access to the full BaZi calculation API. Yearly plans save up to **21%**.
859
+
860
+ ### Monthly Plans
861
+
862
+ | Feature | 🆓 Free | 🚀 Basic | ⚡ Pro | 💎 Premium |
863
+ | ---------------- | :--------------: | :-----------: | :-----------: | :-------------: |
864
+ | **Target** | Developer / Test | Indie Dev | Startup | Enterprise |
865
+ | **Price** | $0 / mo | $19 / mo | $49 / mo | $149 / mo |
866
+ | **Rate Limit** | 30 req / min | 300 req / min | 500 req / min | 1,000 req / min |
867
+ | **API Keys** | 1 | 3 | 10 | Unlimited |
868
+ | **14-Day Trial** | ✅ | ❌ | ❌ | ❌ |
869
+
870
+ ### Yearly Plans _(Save up to 21%)_
871
+
872
+ | Feature | 🆓 Free | 🚀 Basic | ⚡ Pro | 💎 Premium |
873
+ | ---------------------- | :----------: | :-----------: | :-----------: | :-------------: |
874
+ | **Price** | $0 | $15 / mo | $39 / mo | $119 / mo |
875
+ | **Billed Annually** | — | $180 / yr | $468 / yr | $1,428 / yr |
876
+ | **Savings vs Monthly** | — | ~21% off | ~20% off | ~20% off |
877
+ | **Rate Limit** | 30 req / min | 300 req / min | 500 req / min | 1,000 req / min |
878
+ | **API Keys** | 1 | 3 | 10 | Unlimited |
879
+
880
+ > 💡 **Need more?** Contact us for custom enterprise plans with higher rate limits and dedicated support.
881
+
882
+ 👉 **[Get your API Key & View Details here](https://your-saas-website.com/pricing)** _(update this link)_
883
+
884
+ ---
885
+
886
+ ## Support
887
+
888
+ - **Email:** support@your-saas-website.com _(update this email)_
889
+ - **Documentation:** [https://docs.your-saas-website.com](https://docs.your-saas-website.com) _(update this link)_
890
+
891
+ ---
892
+
893
+ ## License
894
+
895
+ MIT © [Md. Nasir Uddin Shoyas](https://github.com/shoyas)