⚡ 5-Minute Guide

Quickstart

Go from zero to your first deal in 5 minutes. Create a server-side API key, generate a widget publishable key, embed the widget, and start closing deals.

Pick a Starting Surface

Salesbooth exposes more than one API shape. Start with the smallest spec that matches what you are building.

SurfaceBest forSpec
Core Commerce APICustomers, products, deals, contracts, payments, webhooks, and commerce schemas/api/core-openapi.json
Widget APIWidget config, saved configs, pricing previews, validation, analytics, and bookings/api/widget-openapi.json
Agent APIDiscovery, negotiation, delegation, trust, tools, and workflows/api/agent-openapi.json
Legacy Public AliasThe filtered public-plus-widget compatibility document used by earlier tooling/api/public-openapi.json
Public Compatibility APIThe default public OpenAPI document for external integrations, combining core commerce and widget surfaces without admin or internal routes./api/openapi.json

Build This First

Most teams should begin with one concrete flow instead of reading the full reference front to back.

Build a server-side deal flow

Create customer → create deal → add products → send contract → collect payment. Use this when your server owns the checkout flow and Salesbooth manages the deal lifecycle behind it.

Build an embedded commerce flow

Embed widget → save config → convert to deal. Use this when you want browser-led product configuration with a publishable key and a widget handoff into a deal.

Build an agent-first commerce flow

Agent discovers offer → negotiates → signs → pays. Use this when your integration is agent-first and needs tooling, trust, and executable workflows.

Recommended starting path

The rest of this quickstart follows the server-side deal flow because it is the fastest path to a first successful integration.

Step 1: Create an API Key

Sign in to your Salesbooth account, navigate to Developers → API Keys, and create a new key.

Recommended scopes for a typical integration

Select only the scopes your integration needs. Start with these for a basic CPQ flow:

ScopeWhy you need it
products:readList and retrieve products for the widget
deals:writeCreate deals when customers complete checkout
customers:writeCreate or look up customer records
webhooks:writeRegister webhooks to receive deal lifecycle events
Sandbox Keys

Prefix your key with sb_test_ for sandbox mode. Sandbox deals don't charge real payment methods and can be reset at any time from Developers → Sandbox.

Your API key looks like this:

sb_test_au_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
Keep your key secret

Never expose sb_test_ or sb_live_ API keys in client-side JavaScript. Use those keys only server-side. For browser widgets, create a widget config and embed the returned sb_pub_ publishable key. That key has restricted widget scope: products:read, customers:write, deals:write, and agent:negotiate.

Step 2: Install the SDK

Choose your integration method:

<!-- Add to your HTML <head> --> <script src="https://salesbooth.com/sdk/v1/salesbooth-widget.js"></script>
npm install @salesbooth/node @salesbooth/sdk
// ES Module import { SalesBooth } from '@salesbooth/node'; const sb = new SalesBooth({ apiKey: 'sb_test_...' });
pip install salesbooth
import salesbooth client = salesbooth.SalesBooth(api_key="sb_test_...")
# No installation needed — use curl directly export SB_API_KEY="sb_test_..." export SB_BASE="https://api.salesbooth.com/v1"

Step 3: Create Your First Product

Products are what your customers buy. Create one via the API or the Salesbooth dashboard.

curl -X POST https://api.salesbooth.com/v1/products \ -H "Authorization: Bearer $SB_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Professional Plan", "description": "Full-featured plan for growing teams", "price": 99.00, "price_type": "once_off" }'
# Response { "error": false, "success": true, "data": { "product": { "product_id": "prod_a1b2c3d4", "version": 1, "name": "Professional Plan", "price": 99.00, "price_type": "once_off", "status": "active", "created_at": "2026-03-09T10:30:00Z" } } }
const { SalesBooth } = require('@salesbooth/node'); const sb = new SalesBooth({ apiKey: 'sb_test_...' }); async function main() { const product = await sb.products.create({ name: 'Professional Plan', description: 'Full-featured plan for growing teams', price: 99.00, price_type: 'once_off' }); console.log('Product created:', product.product_id); // prod_a1b2c3d4 } main().catch((error) => { console.error(error); process.exitCode = 1; });
import salesbooth client = salesbooth.SalesBooth(api_key="sb_test_...") product = client.products.create( name="Professional Plan", description="Full-featured plan for growing teams", price=99.00, price_type="once_off" ) print("Product created:", product["product_id"]) # prod_a1b2c3d4
Save the product ID

You'll use the product ID (prod_a1b2c3d4) and a site ID (site_a1b2c3d4) to create a widget config in the next step.

Step 4: Create a Widget Config

Create a widget from Developers → Widget in the dashboard, or call POST /api/v1/widget-config. This step generates the browser-safe sb_pub_ publishable key used by the embed snippet.

Prerequisite: have a site ID ready

POST /api/v1/widget-config requires an existing site_id. Before running the request below, create or select a site in the dashboard, then copy its site_id from Developers → Widget or Websites → Sites. The product ID from Step 3 is not enough on its own.

curl -X POST https://api.salesbooth.com/v1/widget-config \ -H "Authorization: Bearer $SB_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "site_id": "site_a1b2c3d4", "title": "Get Started Today", "products": "prod_a1b2c3d4", "currency": "USD", "cta_text": "Complete Purchase" }'
# Response { "error": false, "success": true, "data": { "widget_id": "wgt_a1b2c3d4", "api_key": "sb_pub_au_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4", "api_key_id": "key_a1b2c3d4", "products": "prod_a1b2c3d4", "currency": "USD" } }
const { SalesBooth } = require('@salesbooth/node'); const sb = new SalesBooth({ apiKey: 'sb_test_...' }); async function main() { const widget = await sb.widgets.create({ site_id: 'site_a1b2c3d4', title: 'Get Started Today', products: 'prod_a1b2c3d4', currency: 'USD', cta_text: 'Complete Purchase' }); console.log('Widget publishable key:', widget.api_key); // sb_pub_... } main().catch((error) => { console.error(error); process.exitCode = 1; });
Use the widget config API key in the browser

The embed key comes from data.api_key in the widget-config response. Do not reuse your secret sb_test_ or sb_live_ key in the widget.

Step 5: Embed the Deal Widget

The <salesbooth-deal> web component handles the entire deal flow — product selection, configuration, customer info, payment, and contract signature.

<!DOCTYPE html> <html> <head> <script src="https://salesbooth.com/sdk/v1/salesbooth-widget.js"></script> </head> <body> <salesbooth-deal api-key="sb_pub_your_publishable_key" products="prod_a1b2c3d4" title="Get Started Today" cta-text="Complete Purchase" currency="USD" ></salesbooth-deal> <script> const widget = document.querySelector('salesbooth-deal'); widget.addEventListener('salesbooth:deal-created', (e) => { console.log('Deal created!', e.detail); }); </script> </body> </html>
import { useEffect, useRef } from 'react'; import '@salesbooth/sdk/widget'; // registers <salesbooth-deal> export function CheckoutWidget({ productId }) { const ref = useRef(null); useEffect(() => { const el = ref.current; if (!el) return; const handler = (e) => { console.log('Deal created!', e.detail); }; el.addEventListener('salesbooth:deal-created', handler); return () => el.removeEventListener('salesbooth:deal-created', handler); }, []); return ( <salesbooth-deal ref={ref} api-key="sb_pub_your_key" products={productId} title="Get Started Today" /> ); }
<template> <salesbooth-deal ref="widget" api-key="sb_pub_your_key" :products="productId" title="Get Started Today" /> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue'; import '@salesbooth/sdk/widget'; const props = defineProps(['productId']); const widget = ref(null); function onDealCreated(e) { console.log('Deal created!', e.detail); } onMounted(() => { widget.value?.addEventListener('salesbooth:deal-created', onDealCreated); }); onUnmounted(() => { widget.value?.removeEventListener('salesbooth:deal-created', onDealCreated); }); </script>
Publishable vs Secret Keys

Use your sb_pub_ publishable key in the widget — it's safe to expose in client-side code. It has restricted widget scope: products:read, customers:write, deals:write, and agent:negotiate. Keep your sb_test_ / sb_live_ keys server-side.

Step 6: Handle Deal Events

Listen for widget events to trigger your own workflows — send confirmation emails, update your CRM, provision access, etc.

Client-side events (widget)

const widget = document.querySelector('salesbooth-deal'); // Deal completed by customer widget.addEventListener('salesbooth:deal-created', (e) => { const { dealId, customerEmail, total } = e.detail; console.log(`Deal ${dealId} created for ${customerEmail}, total: $${total}`); // Redirect to thank-you page, trigger analytics, etc. }); // Contract signed (contract accepted) widget.addEventListener('salesbooth:contract-signed', (e) => { provisionAccess(e.detail.contractId); }); // Customer navigates to a new step widget.addEventListener('salesbooth:step-change', (e) => { analytics.track('checkout_step_change', { from: e.detail.from, to: e.detail.to }); });

Server-side events (webhooks)

Configure a webhook endpoint in Developers → Webhooks to receive server-side notifications:

const express = require('express'); const crypto = require('crypto'); const app = express(); app.post('/webhooks/salesbooth', express.raw({ type: 'application/json' }), (req, res) => { const sig = req.headers['x-salesbooth-signature']; const ts = req.headers['x-salesbooth-timestamp']; const secret = process.env.WEBHOOK_SECRET; // Verify signature const signed = `${ts}.${req.body}`; const expected = 'v1=' + crypto.createHmac('sha256', secret).update(signed).digest('hex'); if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) { return res.status(401).json({ error: 'Invalid signature' }); } const event = JSON.parse(req.body); if (event.event === 'deal.created') { console.log('New deal:', event.data.deal_id); // Provision access, send email, etc. } res.json({ received: true }); }); app.listen(3000);
import hmac, hashlib, time, os from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/webhooks/salesbooth', methods=['POST']) def webhook(): sig = request.headers.get('X-Salesbooth-Signature', '') ts = request.headers.get('X-Salesbooth-Timestamp', '') secret = os.environ['WEBHOOK_SECRET'] body = request.get_data() # Verify signature signed = f"{ts}.{body.decode()}" expected = 'v1=' + hmac.new( secret.encode(), signed.encode(), hashlib.sha256 ).hexdigest() if not hmac.compare_digest(sig, expected): return jsonify({'error': 'Invalid signature'}), 401 event = request.get_json(force=True) if event['event'] == 'deal.created': print('New deal:', event['data']['deal_id']) return jsonify({'received': True})
<?php $payload = file_get_contents('php://input'); $sig = $_SERVER['HTTP_X_SALESBOOTH_SIGNATURE'] ?? ''; $ts = $_SERVER['HTTP_X_SALESBOOTH_TIMESTAMP'] ?? ''; $secret = getenv('WEBHOOK_SECRET'); // Verify signature $signed = $ts . '.' . $payload; $expected = 'v1=' . hash_hmac('sha256', $signed, $secret); if (!hash_equals($expected, $sig)) { http_response_code(401); exit('Invalid signature'); } $event = json_decode($payload, true); if ($event['event'] === 'deal.created') { error_log('New deal: ' . $event['data']['deal_id']); } echo json_encode(['received' => true]);

See the Webhook Integration Guide for full details on signature verification, retry logic, and event types.

Scope Selection Matrix

Choose the minimum scopes for your use case to follow the principle of least privilege.

Use Case Required Scopes
Embed checkout widget only products:read, deals:write, customers:write
Read deal reports deals:read, customers:read
Manage products & pricing products:write
Process payments deals:write, deals:read
Receive webhooks webhooks:write (to create endpoint)
Manage contracts contracts:write, deals:read
CRM sync (read customers) customers:read
AI agent automation deals:write, delegations:write, agent:discover
Analytics & reporting admin:read, deals:read
Full CPQ workflow products:read, deals:write, customers:write, contracts:write
Team management team:write
Subscription billing deals:write, customers:read

Next Steps

You've created your first integration. Here's where to go next: