Forms SDK
The Default Forms SDK makes it easy to connect your hosted forms to Default’s platform. It streamlines form submissions, event management, and scheduler integration to enhance your workflows.
Forms SDK is used by customers like Hex to fully customize the form experience.
Features:
Form Submission Management. Effortlessly send form data to Default.
Event Emission. Hook into events like submission success or errors.
Scheduler Integration. Allow users to book meetings directly from your form.
Implementation
1. Create a form
Go to Default > Forms > Webforms and create a new form.
Pick Default SDK.
2. Include the forms SDK web script
Add the SDK to your webpage:
const script = document.createElement('script'); script.src = "https://import-cdn.default.com/sdk.js"; script.async = true; // Optional: Load asynchronously document.head.appendChild(script);
Access the SDK:
const sdk = window.DefaultSDK;
3. Available methods
helloworld()
: Logs a welcome message to verify that the SDK is loaded correctly.
sdk.helloWorld(); // Logs: "Hello World! Welcome to Default.com"
submit()
: Sends form responses to Default and manages your event callbacks based on workflow steps.
sdk.submit( submission: { form_id: number; team_id: number; responses: Record<string, string | number | boolean>; questions: Array<{ id: string; name: string; type: string; options?: Array<string | number>; }>; }, callbacks?: { onSuccess?: (data) => void; onError?: (error: Error) => void; onSchedulerDisplayed?: (data) => void; onSchedulerClosed?: (data: { redirectUrl?: string }) => void; onMeetingBooked?: (data: { payload }) => void; } ): Promise<void>;
4. Submission and Callbacks
Submission
Required javascript object containing form data and metadata:
form_id
(number, required): Unique form identifierteam_id
(number, required): Team identifierresponses
(object, required): Question ID to response mappingquestions
(array, required): Question metadata array
Question attributes
For each object in the question
array, the following key value pairs are required:
id
(required): The unique identifier for the question.name
(required): The human-readable name of the question.type
(required): The type of question input:email
: The lead's email address.input
: Short Text input fields.textarea
: Long Text input fields.
select
orradio
: Single Select input where leads can only select one option.
checkbox
orselect-multiple
: Multi Select input where leads can select multiple options.
tel
: Phone number.
options
(optional): For multiple-choice questions, an array of valid options.lead_attribute
(optional): The lead attribute in Default you want to map the input field to:first_name
: The lead's first name.
last_name
: The lead's last name.
phone
: The lead's phone number.
role
: The lead's role at their company.
title
: The lead's job title.
city
: The city that the lead is located in.
location
: The address of the lead.
company
: The company's name.
industry_group
: The company's industry.
head_count
: The company's headcount.
Example submission:
const submission = { form_id: FORMID, team_id: TEAMID, responses: { email: "test@test.com", industry: "automotive", }, questions: [ { id: "email", name: "Email", type: "email", options: [], }, { id: "industry", name: "Industry", type: "input", options: ["automotive", "computers", "software"], }, ], };
Callbacks (Optional)
The following event handlers are available through the lifecycle of a form submission:
const callbacks = { onSuccess: (data) => { console.log("Submission successful!", data); }, onError: (error) => { console.error("Submission failed:", error.message); }, onSchedulerDisplayed: (data) => { console.log("Scheduler displayed:", data); }, onSchedulerClosed: (data) => { console.log("Scheduler closed, optional redirect: " + data.redirect); }, onMeetingBooked: (data) => { console.log("Meeting booked successfully!", data.payload); }, };
Scheduler display control
Use this when you need to have control over where and when a scheduler is displayed.
// Disable automatic scheduler display and manually control when/where it appears DefaultSDK.submit(submission, { autoSchedulerDisplay: false, // Prevents automatic scheduler display onSuccess: (response) => { console.log("Submission successful:", response); // Display scheduler in custom iframe const iframe = document.getElementById("scheduler"); if (iframe) { iframe.style.display = "block"; iframe.src = response.body.stepDetails.url; } } });
When autoSchedulerDisplay
is set to false
, the scheduler won't automatically appear after form submission. Instead, you receive the scheduler URL in the onSuccess
callback, giving you full control over when and where to display it. All scheduler-related callbacks (onSchedulerDisplay
, onSchedulerClosed
, onMeetingBooked
) continue to fire normally, allowing you to maintain full visibility into the scheduler's lifecycle while customizing its presentation.
5. Create a test submission
Create a test submission by submitting a form entry to ensure your setup is working properly. Then, navigate to the Check the Connection step in Default to verify the integration.Complete the Configuration by:
Select the email field to identify the lead.
Map your form fields to the corresponding Default attributes.
Assign a unique name to the form for easy identification.
This process ensures your form is correctly integrated and ready for future submissions.
Forms SDK example
Below is an example snippet that submits a form response using forms SDK.
const script = document.createElement('script'); script.src = "https://import-cdn.default.com/sdk.js"; script.async = true; script.onload = function() { console.log("SDK script loaded, attempting to use DefaultSDK..."); const submission = { form_id: 867190, team_id: 7, responses: { email: "luke@tatooine.galaxy", rebel_name: "Luke Skywalker", home_planet: "Tatooine", spacecraft_type: "X-wing", combat_experience: "Yes", force_sensitive: "Yes", preferred_division: "starfighter_corps", mission_availability: "immediate", droid_companion: "R2-D2", imperial_history: "No" }, questions: [ { id: "email", name: "Contact Email", type: "email", options: [] }, { id: "rebel_name", name: "Full Name", type: "input", options: [] }, { id: "home_planet", name: "Home Planet", type: "input", options: [] }, { id: "spacecraft_type", name: "Primary Spacecraft", type: "select", options: ["X-wing", "Y-wing", "A-wing", "B-wing", "Other"] }, { id: "combat_experience", name: "Do you have combat experience?", type: "select", options: ["Yes", "No"] }, { id: "force_sensitive", name: "Are you Force-sensitive?", type: "select", options: ["Yes", "No"] }, { id: "preferred_division", name: "Preferred Division", type: "select", options: ["starfighter_corps", "ground_forces", "intelligence", "support_services"] }, { id: "mission_availability", name: "When can you start missions?", type: "select", options: ["immediate", "within_week", "within_month", "need_training"] }, { id: "droid_companion", name: "Droid Companion (if any)", type: "input", options: [] }, { id: "imperial_history", name: "Have you ever served the Empire?", type: "select", options: ["Yes", "No"] } ] }; const callbacks = { onSuccess: (data) => console.log("Welcome to the Rebellion!", data), onError: (error) => console.error("Submission failed:", error.message), onSchedulerDisplayed: (data) => console.log("Scheduler displayed:", data), onSchedulerClosed: (data) => console.log("Scheduler closed:", data), onMeetingBooked: (data) => console.log("Meeting booked:", data.payload) }; try { console.log("Attempting submission with DefaultSDK..."); // Using the DefaultSDK that we found in the window properties window.DefaultSDK.submit(submission, callbacks); } catch (e) { console.error("Error during submission:", e); console.log("DefaultSDK object:", window.DefaultSDK); } }; script.onerror = function() { console.error("Failed to load the Forms SDK"); }; document.head.appendChild(script);
Content Security Policy
If adding to a Content Security Policy (CSP), add *.default.com
to your existing lists.For a more specific list of subdomains, you can add the following:
script-src 'self' https://import-cdn.default.com; style-src 'self' https://import-cdn.default.com; connect-src 'self' https://nucleus.default.com;
Error handling
Client-Side validation (SDK errors emitted via callback)
Errors will be triggered if:
Any of the following fields:
form_id
,team_id
,responses
,questions
, oremail
are missingresponses
is not an objectquestions
is not an arrayA
response
key does not match or correspond to an entry in the questions array
Server-Side Errors (400 Bad Request)
The server will return a 400
error if:
submission
is missingform_id
orteam_id
is missingresponses
orquestions
are missingemail
is missingThe
questions[]
array does not match the expected formatNo valid responses are found
Server-Side Errors (500 Internal Server Error)
The endpoint is experiencing an outage
Response structure
Success
{ "body": { "stepDetails": { "inline": true, // If true, display a scheduler modal; if false, redirect to a URL "url": "https://example.com/scheduler-or-redirect-url" } }, "success": true }
Error
{ "error": "Error message explaining why the response was not processed.", "success": false }