{"_id":"@aimbig/integration-sdk","name":"@aimbig/integration-sdk","dist-tags":{"latest":"1.2.0"},"versions":{"1.2.0":{"name":"@aimbig/integration-sdk","version":"1.2.0","description":"Typed client + webhook signature verification for the BIG Integration API (v1.2). Zero runtime dependencies; Node 18+.","license":"MIT","homepage":"https://www.bigapp.online/api-docs.html","repository":{"type":"git","url":"git+https://github.com/aim-big/big-app.git","directory":"packages/integration-sdk"},"keywords":["big","bigapp","booking","appointments","crm","webhooks","api-client"],"sideEffects":false,"publishConfig":{"access":"public"},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"engines":{"node":">=18"},"scripts":{"build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit","test":"vitest run","prepublishOnly":"pnpm build && pnpm test"},"devDependencies":{"@types/node":"^20","typescript":"^5","vitest":"^4.1.4"},"_id":"@aimbig/integration-sdk@1.2.0","gitHead":"5c66b88850e7f562ddfec97dab9bf30c4a0e43b3","bugs":{"url":"https://github.com/aim-big/big-app/issues"},"_nodeVersion":"22.22.2","_npmVersion":"10.9.7","dist":{"integrity":"sha512-KmCLfNa7KU1AKQT5BjEOfUxfrqdsnpijjpBdhn+PM1w/pIdWenm+8G46vyKoKgiwvdBTOskGUl7rjNNIzpbfCQ==","shasum":"02fe2ba4b1f16c836c37b4f6398d253d610fb072","tarball":"https://registry.npmjs.org/@aimbig/integration-sdk/-/integration-sdk-1.2.0.tgz","fileCount":13,"unpackedSize":26774,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDXgoswG9QgpBNWUWsfvWWGon4cutAG770kr+cx8j2PGAIhAJwVpEuDst1qRX+0bh9VoA0rhnlBfC+u3REFfieeIswf"}]},"_npmUser":{"name":"leizhiguang","email":"leizhiguang1@gmail.com"},"directories":{},"maintainers":[{"name":"leizhiguang","email":"leizhiguang1@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/integration-sdk_1.2.0_1783851053365_0.6813651887671393"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-12T10:10:53.113Z","1.2.0":"2026-07-12T10:10:53.504Z","modified":"2026-07-12T10:10:53.760Z"},"maintainers":[{"name":"leizhiguang","email":"leizhiguang1@gmail.com"}],"description":"Typed client + webhook signature verification for the BIG Integration API (v1.2). Zero runtime dependencies; Node 18+.","homepage":"https://www.bigapp.online/api-docs.html","keywords":["big","bigapp","booking","appointments","crm","webhooks","api-client"],"repository":{"type":"git","url":"git+https://github.com/aim-big/big-app.git","directory":"packages/integration-sdk"},"bugs":{"url":"https://github.com/aim-big/big-app/issues"},"license":"MIT","readme":"# @aimbig/integration-sdk\n\nTyped TypeScript client + webhook verification for the **BIG Integration API**\n(v1.2). Zero runtime dependencies, Node 18+ (uses global `fetch` and\n`node:crypto`).\n\nCanonical API reference: [docs/integrations/API.md](../../docs/integrations/API.md)\n· live spec: <https://www.bigapp.online/chatdiddy-api.json>\n· browsable: <https://www.bigapp.online/api-docs.html>\n\n## Install\n\n```sh\nnpm install @aimbig/integration-sdk\n```\n\nInside this monorepo nothing consumes it — it exists for partner apps\n(DMBox/ChatDiddy or any CRM). Alternative for a repo on the same machine\n(no registry needed):\n\n```jsonc\n// package.json\n\"dependencies\": { \"@aimbig/integration-sdk\": \"file:../big-app/packages/integration-sdk\" }\n```\n\nthen `pnpm --filter @aimbig/integration-sdk build` here first (emits `dist/`).\n\nPublishing a new version: bump `version`, then `npm publish` from this\ndirectory (`prepublishOnly` rebuilds and runs the tests). Keep the package\nversion in lockstep with the API version in\n[apps/web/public/chatdiddy-api.json](../../apps/web/public/chatdiddy-api.json).\n\n## Client\n\n```ts\nimport { BigClient, BigApiError } from \"@aimbig/integration-sdk\";\n\nconst big = new BigClient({ apiKey: process.env.BIG_API_KEY! });\n\n// Discovery → availability → book (the golden path)\nconst { outlets } = await big.outlets();\nconst { slots } = await big.availability({ days: 7 });\nconst booking = await big.bookAppointment({\n  start_at: slots[0].start_at,\n  customer: { phone: \"+60123456789\", name: \"Sara\" },\n  external_ref: \"my-crm-12345\", // idempotent replay key\n});\n\n// CRM contact sync (v1.2)\nconst created = await big.createCustomer({\n  name: \"Sara Binti Ali\",\n  phone: \"+60123456789\",\n  tags: [\"lead\"],\n  external_ref: \"dmbox-contact-8842\", // replay-safe retries\n});\nawait big.updateCustomer(created.id, { tags: [\"lead\", \"vip\"] }); // replaces whole list\n\ntry {\n  await big.getCustomer(\"KL01-000999\");\n} catch (err) {\n  if (err instanceof BigApiError && err.code === \"NOT_FOUND\") {\n    // err.details may carry valid_options for self-correction\n  }\n}\n```\n\n`baseUrl` defaults to `https://api.bigapp.online/v1`; pass\n`https://www.bigapp.online/api/integrations` to use the legacy base — same\nroutes, same shapes.\n\n## Webhooks\n\nRegister your receiver in BIG (Config → Integrations → Webhooks), then:\n\n```ts\nimport { constructWebhookEvent, WebhookVerificationError } from \"@aimbig/integration-sdk\";\n\n// Express: capture the EXACT raw bytes — re-serialized JSON won't verify.\napp.post(\"/hooks/big\", express.raw({ type: \"application/json\" }), (req, res) => {\n  let event;\n  try {\n    event = constructWebhookEvent(\n      process.env.BIG_WEBHOOK_SECRET!, // whsec_…\n      req.body,                        // Buffer\n      req.get(\"X-BIG-Signature\") ?? \"\",\n    );\n  } catch (err) {\n    if (err instanceof WebhookVerificationError) return res.status(400).end();\n    throw err;\n  }\n\n  res.status(200).end(); // ack fast (10s budget), process async\n\n  // Dedupe on event.id (at-least-once), treat as upserts (no ordering).\n  switch (event.type) {\n    case \"customer.created\":\n    case \"customer.updated\":\n      // event.data: flat customer body; event.data.changes = { field: { from, to } }\n      break;\n    case \"appointment.status_changed\":\n      // event.data.changes.status = { from, to }\n      break;\n  }\n});\n```\n\n## Field notes for CRM integrators\n\n- **Phone is the join key** — always `+`-prefixed E.164; the client\n  percent-encodes it in query strings for you.\n- **`external_ref` everywhere** — send your own stable id on `bookAppointment`\n  and `createCustomer`; retries replay instead of duplicating, and webhooks\n  echo it back so you can drop echoes of your own writes.\n- **The lead trap** — a booking whose phone matches 0 or 2+ customers creates\n  a *lead*: webhook `customer` is `null`, `is_lead` is `true`. Store\n  `booking_ref` and pick up `customer_id` from a later event.\n- **Tags replace wholesale** — read-modify-write to add/remove a single tag.\n","readmeFilename":"README.md","_rev":"1-b0c5a60fee3a9045d4e944518c9c7f66"}