How It Works
Understand the architecture, communication flow, and lifecycle of a SyncBooks add-on.
Architecture Overview
When a user opens your add-on in SyncBooks, here's what happens:
┌──────────────────────────────────────────────────────────┐
│ SyncBooks Web App (Next.js) │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Extension Host Component │ │
│ │ (manages the iframe lifecycle) │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────┐ │ │
│ │ │ YOUR ADD-ON (sandboxed iframe) │ │ │
│ │ │ │ │ │
│ │ │ - Loaded from YOUR hosting (Vercel, etc.) │ │ │
│ │ │ - Runs YOUR code (React, Vue, anything) │ │ │
│ │ │ - Communicates via postMessage bridge │ │ │
│ │ │ - Makes API calls with session token │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────┘ │ │
│ │ ↕ window.postMessage │ │
│ └──────────────────────────────────────────────────┘ │
│ │
└────────────────────────┬─────────────────────────────────┘
│ HTTPS API calls
▼
┌──────────────────────────────────────────────────────────┐
│ SyncBooks Backend (Express.js) │
│ │
│ /api/addon/v1/* endpoints │
│ ├─ addonSessionAuth middleware (validates JWT) │
│ ├─ addonRateLimit middleware (1000 req/hour) │
│ ├─ addonAuditLog middleware (logs every call) │
│ └─ requireAddonScope middleware (enforces permissions) │
│ │
│ → MongoDB (organization-scoped data) │
└──────────────────────────────────────────────────────────┘Communication Flow
The add-on and SyncBooks communicate through two channels:
1. postMessage Bridge (UI Communication)
For real-time UI interactions between your add-on and the SyncBooks host:
Your Addon SyncBooks Host
───────── ──────────────
│ │
│──── syncbooks:ready ───────────────→│ "I'm loaded"
│ │
│←─── syncbooks:context ─────────────│ "Here's your session"
│ {orgId, userId, token, scopes} │
│ │
│──── syncbooks:navigate ───────────→│ "Go to /invoices/123"
│ │
│──── syncbooks:notify ─────────────→│ "Show success toast"
│ │
│──── syncbooks:close ──────────────→│ "Close me"
│ │
│──── syncbooks:resize ─────────────→│ "Set height to 800px"
│ │2. REST API (Data Access)
For reading and writing data:
Your Addon SyncBooks API
───────── ─────────────
│ │
│── GET /api/addon/v1/customers ────→│
│ Authorization: Bearer <token> │
│ │
│←── 200 { data: [...], total: 42 } ─│
│ │
│── POST /api/addon/v1/invoices ───→│
│ { customerId, lineItems, ... } │
│ │
│←── 201 { data: { _id, ... } } ────│
│ │Session Lifecycle
- User clicks your add-on in SyncBooks (sidebar, action button, etc.)
- SyncBooks creates a session — a JWT containing org ID, user ID, app ID, and granted scopes
- Extension Host loads your iframe — passes the token via URL params
- Your SDK picks up the token —
SyncBooksProviderhandles this automatically - SDK sends "ready" message — SyncBooks responds with full context
- Your add-on renders — using the context and making API calls
- Token expires after 1 hour — user needs to reload to get a new session
Token handling is automatic
The SyncBooksProvider component handles all token extraction, context receiving, and API authorization automatically. You never need to manage tokens manually.
Permission System (Two Layers)
Layer 1: What the add-on CAN access
When you register your add-on, you declare which scopes you need (e.g., invoices.read, customers.write). The organization admin grants a subset of these during installation.
Layer 2: Who CAN use the add-on
The org admin decides which roles/users can see and use your add-on. This is configured after installation.
Developer declares: ["invoices.read", "customers.read", "customers.write"]
↓
Org admin grants: ["invoices.read", "customers.read"] ← they didn't grant write
↓
API enforces: GET /customers → ✅ allowed
POST /customers → ❌ 403 Forbidden (scope not granted)Event System
Your add-on can subscribe to events that happen in SyncBooks:
1. Your addon calls: POST /events/subscribe
{ event: "invoice.paid", webhookUrl: "https://myapp.com/hook" }
2. Later, an invoice gets paid in SyncBooks
3. SyncBooks sends a POST to your webhookUrl:
{
event: "invoice.paid",
data: { invoiceId: "...", amount: 5000 },
timestamp: "2026-08-13T10:30:00Z"
}
Headers: X-SyncBooks-Signature: sha256=abc123...
4. Your server verifies the signature and processes the eventRate Limiting
Each add-on is limited to 1,000 API requests per hour per organization. The response includes headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1691920000 (Unix timestamp when limit resets)If you exceed the limit, you'll receive a 429 Too Many Requests response with a Retry-After header.
Optimize your API usage
Use pagination (limit param), cache data client-side, and batch related reads together. Don't poll — use webhooks for real-time updates.