JavaScript SDK
Lightweight client library for the Salesbooth REST API. Manage deals, customers, products, contracts, and more from any JavaScript environment.
Installation
Load the SDK via a script tag. The SDK is served from your Salesbooth instance with proper CORS and caching headers.
Script Tag
<script src="https://salesbooth.com/sdk/v1/salesbooth.js"></script>
The SDK uses a UMD wrapper and works in browsers, Node.js, and AMD environments. In a browser, it exposes a global Salesbooth object. In Node.js:
Node.js / CommonJS
const Salesbooth = require('./salesbooth.js');
Quick Start
Initialize the SDK with your API key, then start making API calls. All resource methods return Promises.
Create a deal in 3 steps
const sb = Salesbooth.init({
apiKey: 'sb_live_xxxxx'
});
const customer = await sb.customers.create({
name: 'Jane Smith',
email: 'jane@example.com'
});
const deal = await sb.deals.create({
title: 'Jane Smith — Enterprise Plan',
customer_id: customer.customer_id
});
await sb.deals.addItem(deal.deal_id, {
product_id: 'prod_abc123',
name: 'Enterprise Plan',
unit_price: 499.00,
quantity: 1
});
Initialization
Create a client instance with Salesbooth.init(config). The API key is required.
Full configuration
const sb = Salesbooth.init({
apiKey: 'sb_live_xxxxx',
timeout: 30000,
maxRetries: 3
});
| Option | Type | Description |
| apiKey required |
string |
Your API key. Format: sb_live_* (production) or sb_test_* (testing) |
| timeout |
number |
Request timeout in milliseconds. Default: 30000 |
| maxRetries |
number |
Max retries for network errors and 429 rate limits. Uses exponential backoff. Default: 3 |
Available Resources
Once initialized, the client exposes the following resource objects:
| Property | Description |
| sb.deals | Create, update, and manage deals and line items |
| sb.customers | Create and manage customer records |
| sb.products | Manage products and pricing |
| sb.contracts | Create, sign, and manage contracts |
| sb.webhooks | Subscribe to and manage webhooks |
| sb.audit | Query audit trails and verify integrity |
| sb.discovery | Deal discovery for agent-to-agent commerce |
| sb.negotiations | Propose, counter, accept, and reject deal negotiations |
| sb.templates | Manage and instantiate deal templates |
| sb.configuration | CPQ configuration: schema, validation, pricing, and product families |
| sb.widgets | Manage embedded deal widgets, create from templates, and get embed code |
Events
The SDK emits events when resources are created or updated. Subscribe with sb.on(event, handler) and unsubscribe with sb.off(event, handler).
Listening for events
sb.on('deal.created', function(deal) {
console.log('New deal:', deal.deal_id);
});
sb.on('*', function(eventName, data) {
console.log(eventName, data);
});
| Event | Trigger |
deal.created | A new deal is created via sb.deals.create() |
deal.updated | A deal is updated, or items are added/removed |
deal.status_changed | A deal transitions to a new status |
deal.cancelled | A deal is cancelled |
deal.negotiation_proposed | A negotiation proposal is submitted |
deal.negotiation_counter_proposed | A counter-proposal is submitted |
deal.negotiation_accepted | A negotiation is accepted |
deal.negotiation_rejected | A negotiation is rejected |
customer.created | A new customer is created |
customer.updated | A customer record is updated |
contract.created | A new contract is created |
contract.updated | A contract is updated |
contract.signed | A contract is signed |
contract.activated | A contract is activated |
contract.terminated | A contract is terminated |
rateLimit | Rate limit headers received (limit, remaining, resetAt) |
retry | A request is being retried (attempt, retryAfter, status) |
Error Handling
API errors throw a SalesboothError with structured properties. Network failures and timeouts are automatically retried up to maxRetries times with exponential backoff.
Catching errors
try {
const deal = await sb.deals.get('deal_nonexistent');
} catch (err) {
console.log(err.name);
console.log(err.message);
console.log(err.code);
console.log(err.status);
console.log(err.details);
}
| Property | Type | Description |
| name | string | Always 'SalesboothError' |
| message | string | Human-readable error message |
| code | string | Machine-readable error code (e.g. VALIDATION_ERROR, NOT_FOUND, TIMEOUT, NETWORK_ERROR) |
| status | number | HTTP status code (0 for network/timeout errors) |
| details | any | Additional error context from the API, or null |
Deals
Create, update, and manage deals and their line items. Deals are the core unit of commerce — a structured deal object (SDO) containing customer, line items, pricing, and status.
List deals with optional filters.
| Option | Type | Description |
| limit | number | Max results to return |
| offset | number | Pagination offset |
| status | string | Filter by status: draft, in_progress, pending_signature, pending_payment, awaiting_signatures, partially_accepted, closed, cancelled, expired |
| customerId | string | Filter by customer ID |
| createdAfter | string | ISO date filter |
| createdBefore | string | ISO date filter |
Returns Promise<{ deals, pagination }>
Retrieve a single deal by ID.
Returns Promise<Deal>
Create a new deal. Emits deal.created.
| Field | Type | Description |
| title required | string | Human-readable deal name |
| customer_id | string | The customer this deal belongs to (omit for widget negotiations or draft deals) |
| status | string | Initial status (default: draft) |
| metadata | object | Arbitrary key-value metadata |
Returns Promise<Deal>
Update a deal. Emits deal.updated.
Returns Promise<Deal>
Add a line item to a deal. Emits deal.updated.
| Field | Type | Description |
| product_id required | string | Product to add |
| name required | string | Line item display name |
| unit_price required | number | Price per unit |
| quantity | number | Quantity (default: 1) |
| description | string | Item description |
| configuration | object | Product-specific configuration |
Returns Promise<Deal>
Remove a line item from a deal. Emits deal.updated.
Returns Promise<Deal>
Apply a discount to a deal. Emits deal.updated.
Returns Promise<Deal>
Transition a deal to a new status. Emits deal.status_changed.
Returns Promise<Deal>
Shorthand for transition(dealId, 'closed').
Returns Promise<Deal>
Cancel a deal. Emits deal.cancelled.
Returns Promise<Deal>
Digitally sign a deal. Emits deal.signed.
| Param | Type | Description |
| dealId required | string | Deal ID to sign |
| signerInfo | object | Signer details (name, email, role) |
Returns Promise<Deal>
Set or replace the deal's terms. Emits deal.updated.
| Param | Type | Description |
| dealId required | string | Deal ID |
| terms required | object | Terms object matching the deal terms schema |
Returns Promise<Deal>
Update an existing line item on a deal. Emits deal.updated.
| Param | Type | Description |
| dealId required | string | Deal ID |
| itemId required | string | Line item ID to update |
| data | object | Fields to update: quantity, unit_price, configuration |
Returns Promise<Deal>
Partially accept a deal — accept specific line items while leaving others pending. Emits deal.partially_accepted.
Returns Promise<Deal>
Create a fully configured deal in a single atomic call. Validates products, creates or finds a customer, adds line items, and applies discounts. Emits deal.created.
| Field | Type | Description |
| spec.customer | object | Customer details { name, email, phone?, company? } — creates or finds a customer |
| spec.customer_id | string | Existing customer ID (alternative to spec.customer) |
| spec.items required | array | Line items: [{ product_id, quantity?, configuration?, unit_price? }] |
| spec.discounts | array | Discounts: [{ type, value, code? }] |
| spec.template_id | string | Template ID for defaults |
| spec.currency | string | ISO 4217 currency code |
| spec.notes | string | Deal notes |
| spec.metadata | object | Custom key-value metadata |
| options.validateOnly | boolean | Validate without persisting (dry run) |
Returns Promise<Deal>
Get the revenue settlement breakdown for a closed deal. Returns all settlement records showing how the deal total was distributed among participants, including Stripe transfer IDs and USDC transaction IDs.
Returns Promise<{ settlements }>
Verify a deal's integrity and status — confirms the cryptographic signature chain and that all deal data is internally consistent.
Returns Promise<{ valid, checks }>
Get the valid state transitions available for a deal given its current status. Useful before calling transition() to check which statuses are reachable.
Returns Promise<{ transitions }>
Example: Full deal lifecycle
const deal = await sb.deals.create({ customer_id: 'cust_123' });
const dealId = deal.deal_id;
await sb.deals.addItem(dealId, { product_id: 'prod_abc', quantity: 2 });
await sb.deals.addItem(dealId, { product_id: 'prod_xyz', quantity: 1 });
await sb.deals.applyDiscount(dealId, { type: 'percent', value: 10 });
await sb.deals.transition(dealId, 'in_progress');
await sb.deals.transition(dealId, 'pending_payment');
await sb.deals.close(dealId);
Customers
Create and manage customer records. Customers are linked to deals and contracts.
List customers with optional filters.
| Option | Type | Description |
| limit | number | Max results |
| offset | number | Pagination offset |
| status | string | Filter by status |
| search | string | Search by name or email |
Returns Promise<{ customers, pagination }>
Retrieve a single customer by ID.
Returns Promise<Customer>
Create a new customer. Emits customer.created.
| Field | Type | Description |
| name required | string | Customer full name |
| email required | string | Customer email |
| phone | string | Phone number |
| company | string | Company name |
Returns Promise<Customer>
Update a customer record. Emits customer.updated.
Returns Promise<Customer>
Delete a customer record.
Returns Promise<void>
Products
Manage your product catalog. Products are added to deals as line items.
List products with optional filters.
| Option | Type | Description |
| limit | number | Max results |
| offset | number | Pagination offset |
| status | string | Filter by status |
| type | string | Filter by product type |
| category | string | Filter by category |
| search | string | Search by product name |
Returns Promise<{ products, pagination }>
Retrieve a single product by ID.
Returns Promise<Product>
Create a new product.
Returns Promise<Product>
Update a product.
Returns Promise<Product>
Delete a product.
Returns Promise<void>
Contracts
Create and manage contracts with e-signature support. Contracts can be generated from deals or created independently.
List contracts with optional filters.
| Option | Type | Description |
| limit | number | Max results |
| offset | number | Pagination offset |
| status | string | Filter by status |
| customerId | string | Filter by customer |
| renewalType | string | Filter by renewal type |
| expiringSoon | boolean | Show expiring contracts |
Returns Promise<{ contracts, pagination }>
Retrieve a single contract by ID.
Returns Promise<Contract>
Create a new contract. Emits contract.created.
| Field | Type | Description |
| deal_id | string | Create from a deal — auto-populates customer_id, title, value, start_date, end_date |
| customer_id required* | string | Customer the contract belongs to |
| title required* | string | Contract title |
| value required* | number | Contract value |
| currency | string | Currency code (default: USD) |
| start_date required* | string | Start date (YYYY-MM-DD) |
| end_date required* | string | End date (YYYY-MM-DD) |
| metadata | object | Arbitrary metadata |
* Required unless deal_id is provided.
Returns Promise<Contract>
Update a contract. Emits contract.updated.
Returns Promise<Contract>
Sign a draft contract. Creates a cryptographic signature. Emits contract.signed.
Returns Promise<Contract>
Activate a signed contract. Emits contract.activated.
Returns Promise<Contract>
Terminate an active contract. Emits contract.terminated.
Returns Promise<Contract>
Delete a contract.
Returns Promise<void>
Create a contract from an existing deal. Copies the customer, value, and currency from the deal and sets a 1-year term.
Returns Promise<Contract>
Example: Deal to contract
const contract = await sb.contracts.fromDeal('deal_abc123');
await sb.contracts.sign(contract.contract_id);
await sb.contracts.activate(contract.contract_id);
Webhooks
Subscribe to real-time events. Manage webhook endpoints and view delivery history.
List all registered webhooks.
Returns Promise<{ webhooks, pagination }>
Retrieve a single webhook by ID.
Returns Promise<Webhook>
Register a new webhook endpoint.
| Field | Type | Description |
| url required | string | Endpoint URL to receive events |
| events required | array | Array of events to subscribe to (e.g. ["deal.created"]) |
| active | boolean | Whether the webhook is active (default: true) |
Returns Promise<Webhook>
Update a webhook.
Returns Promise<Webhook>
Delete a webhook.
Returns Promise<void>
Rotate the signing secret for a webhook. Returns the new secret.
Returns Promise<{ secret }>
View delivery history for a webhook, including HTTP status codes and response times.
| Option | Type | Description |
| limit | number | Max results |
| offset | number | Pagination offset |
| status | string | Filter by delivery status |
| eventType | string | Filter by event type |
Returns Promise<{ deliveries, pagination }>
Create a new webhook subscription.
| Field | Type | Description |
| url required | string | Endpoint URL to receive events |
| events required | array | Array of event types to subscribe to |
| description | string | Human-readable description |
| active | boolean | Whether active on creation (default: true) |
Returns Promise<Webhook>
Delete a webhook subscription. Sends If-Match header automatically from the cached ETag.
| Option | Type | Description |
| version | number | Override the ETag version |
Returns Promise<void>
Send a test event to the webhook URL to verify the endpoint is reachable and handling events correctly.
| Param | Type | Description |
| webhookId required | string | Webhook ID |
| eventType required | string | Event type to simulate, e.g. deal.created |
Returns Promise<{ delivery_id, status, response_code }>
Return paginated delivery history for a webhook. Equivalent to deliveries() with camelCase naming.
| Option | Type | Description |
| limit | number | Max results |
| offset | number | Pagination offset |
| status | string | Filter by delivery status |
| eventType | string | Filter by event type |
Returns Promise<{ deliveries, pagination }>
Verify a webhook payload signature (HMAC-SHA256). Convenience instance method — delegates to the module-level Salesbooth.verifyWebhookSignature().
| Param | Type | Description |
| payload required | string | Raw request body as a string |
| signature required | string | X-Salesbooth-Signature header value |
| secret required | string | Webhook signing secret |
| timestamp | string | number | X-Salesbooth-Timestamp header value |
| options.tolerance | number | Max age in seconds (default: 300) |
Returns boolean
List dead-letter queue entries — failed deliveries that exceeded the retry limit and were not successfully delivered.
| Option | Type | Description |
| event_type | string | Filter by event type |
| webhook_id | string | Filter by webhook |
| limit | number | Max results |
| offset | number | Pagination offset |
Returns Promise<{ entries, pagination }>
List webhook event records with optional filters. Useful for auditing which events have been dispatched.
| Option | Type | Description |
| since_sequence | number | Return events after this sequence number |
| since_timestamp | string | Return events after this ISO timestamp |
| event_type | string | Filter by event type |
| status | string | Filter by status |
| limit | number | Max results |
Returns Promise<{ events, pagination }>
Replay webhook events — re-dispatch matching events to all active subscriptions. Use to recover from missed deliveries.
| Field | Type | Description |
| webhook_id | string | Replay only to this webhook |
| since_sequence | number | Replay events from this sequence number |
| since_timestamp | string | Replay events since this ISO timestamp |
| event_type | string | Replay only this event type |
Returns Promise<{ queued }>
Retry a specific failed webhook delivery by its delivery ID.
Returns Promise<{ delivery_id, status }>
Clean up stale webhook data — removes processed events and old delivery records beyond the retention window.
| Option | Type | Description |
| retention_days | number | Keep records newer than this many days |
| batch_size | number | Max records to delete per call |
Returns Promise<{ deleted }>
Audit
Every entity has an immutable, cryptographically chained audit trail. Query and verify the integrity of audit logs.
Retrieve the audit trail for an entity.
| Param | Type | Description |
| entityType required | string | deal, contract, customer, or product |
| entityId required | string | The entity identifier |
| options.limit | number | Max results |
| options.offset | number | Pagination offset |
Returns Promise<{ entries, pagination }>
Verify the cryptographic hash chain integrity of an entity's audit trail. Returns whether all entries are intact and untampered.
Returns Promise<{ valid, entries_checked }>
Example
const trail = await sb.audit.list('deal', 'deal_abc123');
const result = await sb.audit.verify('deal', 'deal_abc123');
console.log(result.valid);
Discovery
Deal discovery for agent-to-agent commerce. Browse available deals and products by category, price range, and payment terms.
Browse discoverable deals.
| Option | Type | Description |
| category | string | Filter by category |
| minPrice | number | Minimum price |
| maxPrice | number | Maximum price |
| currency | string | Currency code |
| pricingModel | string | Filter by pricing model |
| paymentTerms | string | Filter by payment terms |
| limit | number | Max results |
| offset | number | Pagination offset |
Returns Promise<{ deals, pagination }>
Get the discovery schema — available categories, pricing models, and filter options.
Returns Promise<DiscoverySchema>
Negotiations
Propose, counter, accept, or reject deal negotiations. Includes AI-powered negotiation intelligence.
Get the full negotiation history for a deal.
Returns Promise<{ negotiations }>
Submit a negotiation proposal. Emits deal.negotiation_proposed.
Returns Promise<Negotiation>
Submit a counter-proposal. Emits deal.negotiation_counter_proposed.
Returns Promise<Negotiation>
Accept the current negotiation. Emits deal.negotiation_accepted.
Returns Promise<Negotiation>
Reject the current negotiation with an optional reason. Emits deal.negotiation_rejected.
Returns Promise<Negotiation>
Get AI-powered negotiation intelligence for a deal — suggested strategies, BATNA analysis, and optimal pricing.
Returns Promise<NegotiationIntelligence>
Request an AI-generated negotiation suggestion based on current terms. Returns proposed counter-terms with reasoning. Emits negotiation.suggestion_generated.
| Param | Type | Description |
| dealId required | string | Deal ID |
| currentTerms | object | Current terms snapshot. If omitted, terms are pulled from the deal. |
Returns Promise<NegotiationSuggestion>
Example: Agent-to-agent negotiation
const available = await sb.discovery.discover({
category: 'consulting',
maxPrice: 5000
});
const intel = await sb.negotiations.intelligence(dealId);
await sb.negotiations.propose(dealId, {
proposed_value: 3500,
message: 'Proposing volume discount for recurring engagement.'
});
await sb.negotiations.counter(dealId, {
proposed_value: 4200,
message: 'Can do 4200 with 30-day payment terms.'
});
await sb.negotiations.accept(dealId);
Templates
Create reusable deal templates to standardize your sales process. Instantiate templates to create pre-configured deals.
List deal templates.
| Option | Type | Description |
| status | string | Filter by status |
| category | string | Filter by category |
| search | string | Search templates |
| limit | number | Max results |
| offset | number | Pagination offset |
Returns Promise<{ templates, pagination }>
Retrieve a single template by ID.
Returns Promise<Template>
Create a new deal template.
Returns Promise<Template>
Update a template.
Returns Promise<Template>
Delete a template.
Returns Promise<void>
Create a new deal from a template. Pass customer-specific overrides.
Returns Promise<Deal>
List all versions of a template. Every update creates a new immutable version.
Returns Promise<{ versions }>
Retrieve the full content of a specific template version.
Returns Promise<TemplateVersion>
Roll a template back to a specific previous version. Creates a new version with the rolled-back content.
Returns Promise<Template>
Return a structured diff between two template versions.
| Param | Type | Description |
| templateId required | string | Template ID |
| fromVersion required | number | Older version number |
| toVersion required | number | Newer version number |
Returns Promise<{ from, to, diff }>
Example
const deal = await sb.templates.instantiate('tmpl_abc123', {
customer_id: 'cust_xyz',
metadata: { source: 'ai_agent' }
});
Configuration (CPQ)
Programmatic product configuration for AI agent deal building. Get product schemas, validate configurations, calculate pricing with bundle discounts, and browse product families.
Get the full configuration schema for a product — option groups, compatibility rules, and bundle pricing rules in one call.
Returns Promise<{ product_id, options, compatibility_rules, bundle_rules }>
Validate a set of selected option IDs against compatibility and bundle rules. Returns validation result with errors, warnings, and qualifying bundles.
| Param | Type | Description |
| productId required | string | Product ID |
| optionIds required | string[] | Array of selected option IDs |
Returns Promise<{ valid, errors, warnings, qualifying_bundles, price_adjustments }>
Calculate the full price breakdown for a configuration, including base price, option modifiers, and bundle discounts.
Returns Promise<{ product_id, valid, errors, warnings, pricing }>
List product families.
| Option | Type | Description |
| status | string | Filter by status |
| search | string | Search families |
| limit | number | Max results |
| offset | number | Pagination offset |
Returns Promise<{ families, pagination }>
Retrieve a single product family by ID.
Returns Promise<{ family }>
Get all products in a product family.
Returns Promise<{ family_id, products, pagination }>
Example: Agent-Driven Product Configuration
const schema = await sb.configuration.getSchema('prod_abc123');
const optionIds = ['opt_walnut', 'opt_large', 'opt_led'];
const validation = await sb.configuration.validate('prod_abc123', optionIds);
if (!validation.valid) {
console.log('Errors:', validation.errors);
}
const pricing = await sb.configuration.price('prod_abc123', optionIds);
console.log('Total:', pricing.pricing.total);
Batch Operations
Execute up to 25 operations in a single request. Batch operations are transactional — all succeed or all fail.
Example: Create customer + deal + line item in one request
const result = await sb.batch([
{
method: 'POST',
resource: 'customers',
body: { name: 'Acme Corp', email: 'billing@acme.com' }
},
{
method: 'POST',
resource: 'deals',
body: { customer_id: '$batch.0.customer_id' }
},
{
method: 'POST',
resource: 'deals',
id: '$batch.1.deal_id',
action: 'add_item',
body: { product_id: 'prod_abc', quantity: 1 }
}
]);
| Field | Type | Description |
| method required | string | GET, POST, PATCH, or DELETE |
| resource required | string | Resource name: deals, customers, products, etc. |
| id | string | Resource ID (for operations on existing entities) |
| action | string | Action to perform (e.g. add_item, sign) |
| body | object | Request body |
Webhook Verification
Verify incoming webhook signatures to ensure requests are authentic. Salesbooth signs webhook payloads with HMAC-SHA256 and includes a timestamp to prevent replay attacks.
Headers sent with each webhook
| X-Salesbooth-Signature | HMAC-SHA256 signature in format v1=hexdigest |
| X-Salesbooth-Timestamp | Unix timestamp (seconds) when the webhook was sent |
Synchronous (Node.js)
const isValid = Salesbooth.verifyWebhookSignature(
rawBody,
signature,
webhookSecret,
timestamp,
{ tolerance: 300 }
);
Async (Node.js + Browsers)
const isValid = await Salesbooth.verifyWebhookSignatureAsync(
rawBody,
signature,
webhookSecret,
timestamp,
{ tolerance: 300 }
);
Express.js example
const express = require('express');
const Salesbooth = require('./salesbooth.js');
const app = express();
app.post('/webhooks/salesbooth',
express.raw({ type: 'application/json' }),
function(req, res) {
const sig = req.headers['x-salesbooth-signature'];
const ts = req.headers['x-salesbooth-timestamp'];
if (!Salesbooth.verifyWebhookSignature(req.body, sig, process.env.WEBHOOK_SECRET, ts)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = JSON.parse(req.body);
console.log('Received:', event.type);
res.status(200).json({ received: true });
}
);
TypeScript
The SDK ships with full TypeScript definitions. Load the type definitions from the same path as the SDK.
Available at
https://salesbooth.com/sdk/v1/salesbooth.d.ts
Usage with reference directive
const sb = Salesbooth.init({
apiKey: 'sb_test_xxxxx'
});
const deals: Salesbooth.DealListResult = await sb.deals.list({
status: 'in_progress',
limit: 10
});
The type definitions include interfaces for all resources, options, and response types: Deal, Customer, Product, Contract, DealListOptions, SalesboothConfig, SalesboothEvent, and more.