SawStream for Salesforce
SawStream lets you pull live data from your Salesforce org and display it on any website, no backend code required. Connect your Salesforce account once, build a query that defines what object and fields to show, pick a layout (table, cards, calendar, JSON, CSV, etc.), and paste a small embed snippet into your site. Every time someone loads the page, SawStream fetches fresh data from Salesforce and renders it.
Signing in
The admin login page is at /login. Enter your email and password and click Log in.
Contact [email protected] if you have any issues signing in.
Salesforce setup
SawStream connects to Salesforce using OAuth 2.0. You need to create an External Client App in Salesforce first, then paste the credentials into SawStream.
- Log in to your Salesforce org and go to Setup.
- In the Quick Find box, search for App Manager and click it.
- Click New External Client App in the top right.
- Fill in the External Client App Name (anything you like, e.g. "SawStream") and your contact email.
- Under API (Enable OAuth Settings), check Enable OAuth Settings.
- In the Callback URL field, paste the callback URL shown on your SawStream Salesforce settings page. It looks like
https://yourdomain.com/auth/salesforce/callback. Use the exact URL from SawStream, not a guess. - Under Selected OAuth Scopes, add at minimum Manage user data via APIs (api) and Perform requests at any time (refresh_token, offline_access).
- Uncheck Require Proof Key for Code Exchange (PKCE) if it is checked.
- Save the External Client App. Salesforce may take a few minutes to activate it.
- After saving, click Manage Consumer Details to get your Consumer Key (Client ID) and Consumer Secret (Client Secret).
- Go to Salesforce in the sidebar of your SawStream admin.
- Paste your Consumer Key into the Client ID field.
- Paste your Consumer Secret into the Client Secret field.
- If your org is a sandbox, change the Login URL field to
https://test.salesforce.com. Production orgs use the defaulthttps://login.salesforce.com. - Click Save Settings.
- Click Connect to Salesforce. You will be redirected to Salesforce to authorize the app.
- Log in to Salesforce (if prompted) and click Allow.
After authorizing, you are sent back to the SawStream Salesforce settings page. The status shows as Connected with your Salesforce username. You can now create queries against your org.
Queries
A query defines what Salesforce data to fetch and how to display it. Each query gets its own embed code (or URL for JSON/CSV), so you can have as many as you need across different pages.
- Click + New Query from the Dashboard or the Queries page.
- Give the query a name. This is just for your reference inside SawStream.
- Pick a Salesforce Object from the dropdown — Account, Contact, Opportunity, etc. The list is fetched live from your connected org.
- Add the Fields you want to display. Each row has the API field name (e.g.
FirstName) and the display label. Click the field input to search your object's fields. - Choose a Layout. See the Layouts section for what each one does.
- Set Per Page if you want pagination. Leave it blank or set it to 0 to show all records.
- Add a WHERE Clause if you only want a subset of records. Write standard SOQL, for example
IsActive = trueorCreatedDate = LAST_N_DAYS:30. Do not include the word WHERE. - To create a detail page that loads one record by ID, set the filter to
Id = '{!id}'— the{!id}placeholder is replaced with the value of the?id=URL parameter on the embedding page. - If you want a search bar on the embed, turn on Enable Search Bar and add the field API names you want to search against in Search Fields.
- To link each record to a detail page, fill in Detail Link Template. Use
{!FieldName}to insert field values, e.g.https://example.com/contacts/{!Id}. - Click Save Query.
Each query has a Data Freshness setting that controls how often SawStream fetches new data from Salesforce. Choose Live Data for real-time results on every page load, or cache responses for 15 minutes, 1 hour, 6 hours, or 12 hours. Caching reduces API calls against your Salesforce limits and speeds up page loads. Use Live Data for fast-changing records (open opportunities, support cases) and longer caches for stable data (product catalogs, office locations). Settable per query.
From the Queries page: Edit opens the editor (changes take effect immediately for live embeds), Copy Code copies the snippet to your clipboard, Delete removes the query (type DELETE to confirm — this breaks any live embeds using its code, and there is no undo).
Layouts
Each query has a layout that controls how the data appears on your site. Pick the layout when creating or editing a query.
Standard data table with column headers, sortable by clicking, and a sticky first column on narrow screens.
Each record becomes a card — first field is the title, remaining fields show as label/value pairs.
Tighter 3-column layout. Header band with the record name plus compact label/value rows.
Filter sidebar (search box, checkboxes, range sliders) auto-built from your fields, with matching records on the right.
FullCalendar month/week/list views. Required fields: Event title and a Start Date. Color events by a field, hover for popup.
You write a template; SawStream renders it per record. Use {!FieldName} placeholders to insert field values.
Stable JSON URL — fetch it from any frontend, mobile app, or workflow. Same data as the embed.
A URL that triggers a CSV file download. Wire it to a Download button on your site.
Embedding on your site
Once you have a query, go to its detail page to get the embed code. For layouts that produce HTML output, you'll see a two-line snippet like this:
<div class="sawstream-section"></div>
<script src="https://sawstream.com/e/tenant/live.js?q=abcdedquerycodexyz" async></script>
Paste both lines into your website where you want the data to appear. The script tag can go anywhere on the page, including the <head>. When the page loads, the script fetches your query's data and renders it inside the <div class="sawstream-section">.
By default the widget renders inside the nearest .sawstream-section div above the script. For more control, add a data-target attribute pointing to any element on the page:
<script src="https://sawstream.com/e/tenant/live.js?q=abcdedquerycodexyz"
data-target="#my-custom-div" async></script>
For JSON and CSV queries you'll see a plain URL instead of a snippet. The JSON URL returns data as an array of objects; the CSV URL triggers a file download.
Forms (website form → Salesforce)
Queries and layouts display Salesforce data on your site. Forms do the reverse: they capture submissions from a form on your website and create a record in Salesforce — a new Lead, Contact, Account, or any object you choose. You map each web form field onto a Salesforce field, and every submission creates a record automatically.
- Click Forms in the sidebar, then + New Form.
- Give the form a name (for your reference inside SawStream).
- Pick the Salesforce Object to create — Account, Contact, Lead, etc. The list is fetched live from your connected org.
- Add your field mappings. Each row has three parts: a Source, the value, and the Salesforce field it fills (chosen from a dropdown of that object's fields, sorted alphabetically).
- Click Create Form. You'll land on the form's detail page, which shows a unique Submit URL like
https://sawstream.com/f/abc123…. This URL is where your website form's submissions get sent.
Each mapping row's Source dropdown decides where the value comes from:
- Form field — take the value from the submission. Enter the field's key or title (see How fields are matched below).
- Fixed value — write the same value on every submission. Use this for Salesforce fields your web form doesn't ask about, such as
LeadSource=Website, or the requiredCompanyon a Lead.
Form fields the visitor left blank are skipped, so an empty optional field never overwrites existing Salesforce data. Fixed values are always written.
LastName and Company; Account requires Name; Contact requires LastName. Web forms rarely ask for a company name — if yours doesn't, add a Fixed value row for Company (e.g. Website Lead), or every submission will fail with REQUIRED_FIELD_MISSING.Any tool that can send a webhook works. Send an HTTP POST to your Submit URL with Content-Type: application/json and the whole submission as the JSON body. The shape doesn't matter — SawStream searches the payload for your mapped keys at any depth, so you can forward the payload your form tool already sends.
- WordPress — Gravity Forms, WPForms, Contact Form 7 and Elementor Forms all have a webhook or POST action. Point it at the Submit URL.
- Webflow, Framer, Squarespace — send the submission from the form's webhook setting, or via a Make or Zapier step.
- Zapier / Make — use a Webhooks → POST action with the Submit URL and JSON body.
- Your own site — post it directly from your form handler:
await fetch("https://sawstream.com/f/abc123…", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email: "[email protected]", first_name: "Ada" })
});
Your mapping's left-hand values would be email and first_name to match that payload.
Wix sends form submissions to SawStream through a built-in Automation — no code needed. Set it up once per form:
Step 1 — Give each Wix field a stable Field key. In the Wix form editor, select a field, open the Advanced tab, and note (or set) its Field key — e.g. company_name. The Field key is the recommended thing to map against because it doesn't change if you later rename the field's title.
Step 2 — Map the fields in SawStream. In the SawStream Forms editor, for each mapping enter the Wix Field key on the left and pick the Salesforce field on the right. Save, then copy the Submit URL from the form's detail page.
Step 3 — Create the Wix automation.
- In your Wix site dashboard, open Automations and create a new automation.
- Trigger: choose Wix Forms → Form submitted, and select the form you want to capture.
- Action: choose Send HTTP request.
- Set Method to POST.
- Set Body params to Entire payload.
- Paste your SawStream Submit URL into the Webhook URL field.
- Save and activate the automation.
That's it. Each time someone submits the Wix form, the automation posts the submission to SawStream, which maps the fields and creates the record in your Salesforce org.
SawStream reads only the fields the visitor actually filled in. Each Form field mapping's left-hand value is looked for anywhere in the submission payload, at any nesting depth — first as a field key (recommended, e.g. company_name), then as the field's visible title (e.g. Business Name). On Wix the key is the field's Field key; elsewhere it's whatever your form tool names the property in the JSON it sends. Empty fields are skipped, so a blank optional field never overwrites a Salesforce value.
Every submission returns the same JSON response — always these six keys, on success and on failure alike:
{
"ok": true,
"id": "001g500000ZPWoXAAX",
"object": "Account",
"salesforce_status": 201,
"error_code": "",
"error_message": ""
}
When something goes wrong, ok is false and error_code / error_message tell you exactly why — including Salesforce's own wording, passed through unchanged:
{
"ok": false,
"id": "",
"object": "Lead",
"salesforce_status": 400,
"error_code": "REQUIRED_FIELD_MISSING",
"error_message": "Required fields are missing: [Company]"
}
error_code and error_message displays a blank Step Output with just Ok = false — and you'll have no idea why a submission failed. You only need to define it once; the same structure is returned for every form.Check error_message first — it names the cause. The common values of error_code:
REQUIRED_FIELD_MISSING,INVALID_EMAIL_ADDRESS,DUPLICATES_DETECTED… — Salesforce's own codes, passed through. The record was rejected by your org's rules; fix the mapping or the Salesforce configuration.no_mapped_fields— none of your mapped keys were found in the submission. The message lists both the keys you mapped and the keys actually present in the payload, so you can see what to rename.no_connection— Salesforce isn't connected, or the connection was revoked. Reconnect it on the Salesforce page in SawStream, then resubmit.not_entitled— the account isn't on an active plan.no_object— the form has no Salesforce object selected.unknown_form— the Submit URL doesn't match a form. Check for a typo or a deleted form.
HTTP status tells you whether retrying helps: 200 means we handled the request and the outcome is final (even when ok is false) — don't retry. 424 means a temporary problem reaching Salesforce, so a retry is worth it. 404 means the Submit URL is wrong.
From the Forms page: Copy URL copies the Submit URL, Edit reopens the mapping editor (changes take effect immediately), and Delete removes the form. Deleting a form means any website automation still posting to its URL will stop creating records.
Settings
Go to Settings in the sidebar to manage allowed origins for your embeds.
A list of domains allowed to load your embed and call the query API. Enter one domain per line, e.g. https://mysite.com. Only requests from those origins are served.
Leaving this blank allows requests from any domain — fine for testing, but before going live lock it down to your site. You can also set allowed origins per query, overriding the global setting.
Your account
Click the lock icon in the sidebar footer. New passwords must be at least 10 characters, include a number, and include a symbol. Click Update Password when valid.
Click Log out in the sidebar footer. You're redirected to the login page immediately.