Public API
API documentation, fair use policy, webhooks.
Written By Victor Raessen
Last updated 3 days ago
Public API
The Salesbuildr API lets you programmatically access and manage your data. Use it to build custom integrations, automate workflows, or connect Salesbuildr to tools that aren't covered by the built-in integrations.
Note: The Public API is a feature that must be enabled for your account.
API overview
The API follows REST conventions with JSON request and response bodies.
Base URL
All API requests use your tenant-specific URL:
https://[your-tenant-name].salesbuildr.com/public-api/Authentication
Authenticate by passing your API key in the api-key header:
api-key: your-api-key-hereGenerate API keys at Settings > Integrations > API Key. Only users with the Admin role can generate or regenerate keys.
Documentation
Full API specifications are available at:
- API reference β
https://portal.salesbuildr.com/public-api#/(Redocly docs) - Interactive docs β
https://[your-tenant].salesbuildr.com/public-api/swagger(Swagger UI) - Webhook docs β
https://[your-tenant].salesbuildr.com/public-api/webhooks
Available resources
The API provides access to 13 resource endpoints:
Quote search β list vs detail
GET /public-api/quote (and the deprecated GET /public-api/quote/approved) returns a slim quote by default: id, title, number, status, dates, contact, company name, opportunity id, and attachments. The response does not include an items key.
GET /public-api/quote/{id} always returns the full quote, including items[]. Creating a quote (POST) is unchanged.
If an existing integration reads items[] from the list endpoint, switch those reads to GET /public-api/quote/{id}, or contact Salesbuildr to enable line items on quote search for your account.
Reading one quote
items[] is still the flat list of enabled lines, in display order. Bundle headers and optional add-ons that are not selected stay out of that list. Keep reading line prices from items[].
The same response also includes:
product.externalIdentifier is unchanged. When your integration key has a product or line identifier, the response can also include that single key under externalIdentifiers. Identifiers that belong to other integrations are not returned.
Quote search does not include widgets, lines, totals, or mutationSeq unless line items are enabled for quote search on your account.
Creating a quote without a template
templateId is optional on POST /public-api/quote and POST /public-api/quote/approved. Leave it out to create the quote from the opportunity and the products[] you send, without copying a Salesbuildr template.
Updating a draft quote's header
PUT /public-api/quote/{id} updates a draft quote. The same body works on PUT /public-api/quote/ext/{externalIdentifier} for a quote that already exists. That route does not create a quote. The external id is the one stored for the integration-key header. If you omit that header, the key is public-api, which does not match an Autotask, Halo, ConnectWise, or Dynamics id.
Send operationId in the body and an Idempotency-Key header. Include at least one field you want to change. A body that only has operationId is rejected and does not change the quote. Leave a field out to keep its current value. Send null to clear an optional field. title cannot be null or empty.
You can set the title, notes, payment term, contract start, contract duration, discount, shipping, and delivery address. Duration units are months and years. A percentage discount amount is a fraction from 0 to 1 (0.1 is 10%). A fixed discount amount uses the same currency units as line prices.
The quote must still be a draft. A sent, approved, declined, or deleted quote is rejected. Line items and sections are still edited in Salesbuildr.
Optional expectedMutationSeq must match the mutationSeq from GET /public-api/quote/{id}. If someone else saved the quote first, the call is rejected and nothing is written. Send the same Idempotency-Key and the same body to retry a call that already succeeded. A different body with that key is rejected.
The response is the full quote, plus the operationId you sent. Get quote, quote search, and webhooks do not include operationId.
Quote create β per-line pricing
When creating a quote (POST /public-api/quote or POST /public-api/quote/approved), each entry in products[] accepts id, quantity, and an optional price object to override catalog sellable fields for that line:
Omitted fields fall back to the product's catalog values. Unknown keys inside price are rejected.
Example request body:
{ "opportunityId": "abc123", "title": "Integration quote", "products": [ { "id": "product-id", "quantity": 2, "price": { "originalPrice": 150, "cost": 60, "price": 120, "markup": 1, "term": "month" } } ]}Quote line item pricing (response)
Each object in items[] on a quote response includes:
Use originalPrice directly when syncing to external systems. Do not back-calculate it from price and discount β that can introduce rounding errors in tools that store only two decimal places.
| Quote Template | List, Get, Create, Update | Manage quote templates || Category | List, Tree | Read-only. Flat list or hierarchical tree structure || Field | Get values, Upsert values | Manage field dropdown values (opportunity categories, payment terms, etc.) || Pricing Book | List, Get, Create, Update | Manage pricing books with product assignments and company links || Discount Group | List, Get, Create, Update, Set companies | Manage discount groups with category-level discounts || Sync State | Update | Report synchronization status for quotes and products || Contract (Beta) | Search items | Read-only access to contract items. Beta β may change without notice |
External identifiers
Most resources support operations by external identifier β a reference you provide to link Salesbuildr records to your external system. Use GET/PUT/DELETE /public-api/{resource}/ext/{externalIdentifier} to work with records by their external ID.
Pagination and search
Search endpoints support:
fromandsizefor paginationqueryfor text search- Resource-specific filters
- Sort field and direction
Rate limits and fair use
Rate limits
Each tenant is limited to 500 API requests per 10-minute rolling window. This limit applies to Public API calls only β internal application requests and built-in PSA integrations do not count.
When the limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header indicating when requests can resume.
The sync state endpoint is exempt from rate limiting.
Rate limit response headers
Every API response includes headers showing your current rate limit status:
Handling rate limits
Follow these best practices to stay within rate limits and build a resilient integration:
- Use webhooks instead of polling. Subscribe to events (e.g.,
quote.ordered,company.updated) rather than repeatedly calling search endpoints to detect changes. - Implement exponential backoff. When you receive a
429response, wait for the number of seconds specified in theRetry-Afterheader, then retry. If the retry also fails, double the wait time before each subsequent attempt. - Batch where possible. Use batch endpoints (e.g.,
POST /public-api/product/batchfor up to 100 products at a time) instead of creating resources one by one. - Cache responses. Store data locally and refresh only when needed β avoid fetching the same resource repeatedly within a short window.
- Monitor your usage. Check
X-RateLimit-Remainingin response headers to proactively slow down before hitting the limit.
Fair use policy
The API is provided as part of your Salesbuildr subscription for normal integration usage. By using the API, you agree to the following terms:
Permitted uses:
- Synchronizing data between Salesbuildr and your business systems (CRM, PSA, ERP)
- Automating quote creation, product management, or order processing
- Building custom dashboards or reporting tools
- Triggering workflows based on webhook events
Prohibited uses:
- High-volume bulk requests designed to overload the platform
- Continuous polling for changes (use webhooks instead)
- Scraping, data harvesting, or competitive analysis
- Reselling or redistributing API access to third parties
- Circumventing rate limits through multiple API keys or IP rotation
- Any activity that degrades platform performance for other customers
Hosted platform obligations: Salesbuildr is a shared multi-tenant platform. API usage that impacts other customers' experience β even if unintentional β may be throttled or restricted without notice.
Consequences of violation: Salesbuildr reserves the right to restrict API access, suspend accounts, or apply additional usage charges for policy violations. Persistent or intentional abuse may result in account termination.
Policy updates: This policy may be updated at any time. Continued use of the API after changes constitutes acceptance.
For questions about API usage or to request higher rate limits, contact support@salesbuildr.com.
Webhooks
Webhooks notify your external systems in real time when events occur in Salesbuildr. Instead of polling the API for changes, you register endpoint URLs and Salesbuildr pushes event data to them automatically.
Note: Webhooks must be enabled for your account. Navigate to Settings > Integrations > Webhooks to manage your endpoints.
Available events
Salesbuildr supports 16 webhook event types across 6 entities:
Creating a webhook endpoint
- Navigate to Settings > Integrations > Webhooks
- Click Add Webhook
- Configure the endpoint settings:
- Click Save
You can create multiple endpoints, each subscribing to different events. For example, one endpoint for CRM updates and another for order notifications.
Payload structure
Each delivery sends an HTTP POST with a JSON body:
{ "event": "company.created", "eventId": "unique-event-id", "timestamp": "2026-02-20T10:30:00.000Z", "data": { ... }}- event β The event type that triggered the delivery
- eventId β A unique identifier for this specific delivery
- timestamp β ISO 8601 timestamp of when the event occurred
- data β The full entity object, using the same structure as the Public API response for that resource
For example, a company.created event delivers the same company object you'd get from GET /public-api/company/:id.
Delivery and retries
- Deliveries are processed asynchronously via a background job queue
- A delivery is considered successful when your endpoint returns any HTTP 2xx status
- Failed deliveries (non-2xx response or timeout) are retried with a 2-second delay between attempts
- Delivery history is visible per endpoint in the admin UI, showing timestamp, event type, HTTP status, and success/failure
Testing webhooks
Click the Send Test button on any configured endpoint to deliver a test event. This verifies:
- Your URL is reachable from Salesbuildr
- Authentication headers are accepted
- Your endpoint returns a 2xx response
The test delivery uses a sample payload with realistic data so you can verify your integration's parsing logic.
Common patterns
CRM synchronization
Subscribe to company.created, company.updated, contact.created, and contact.updated to keep an external CRM in sync with Salesbuildr customer data.
Order fulfillment
Subscribe to quote.ordered and order.created to trigger fulfillment workflows when a quote is converted to an order.
Reporting and analytics
Subscribe to opportunity.status_changed and quote.created to feed sales metrics into a BI tool or dashboard.
Troubleshooting
- Deliveries not arriving β Verify the endpoint is Active, the URL is reachable from the internet, and you're subscribed to the correct events
- Authentication failures β Check that custom headers match what your endpoint expects
- Timeouts β Ensure your endpoint responds within the configured timeout; process webhook data asynchronously if your handler is slow
- Duplicate deliveries β Use the
eventIdfield to deduplicate; retries may re-deliver the same event
See also
Custom Fields β Settings
Email β Settings
Platform β Settings
Security & Legal β Support
Was this helpful?
More in Admin
PlatformQuotesOpportunitiesDistributorsStill need help? Ask the team