Developers/No-Code SDK
No-Code Integration

No-Code SDK

A lightweight IIFE script hosted at cdn.swake.io/sdk.js — paste one snippet in your HTML head and start identifying users and intercepting portal links with zero npm, zero bundler, zero framework required.

Overview

The No-Code SDK is a self-contained JavaScript snippet you drop into any HTML page. It loads asynchronously from Swake's CDN at roughly 1.9 KB gzipped and makes no assumptions about your tech stack — it works in plain HTML, server-rendered apps, CMS platforms, and marketing sites alike.

Command-queue loader
Calls to Swake() made before the script loads are queued and replayed automatically.
User identification
One call to Swake('identify', …) upserts the user in Swake and registers a delegated click handler.

No UI is rendered by this SDK. It does not display a feedback form, floating button, or any in-app widget. If you need those, use the @swake/react-native or @swake/web SDK integration instead.


Installation

Two steps — paste both snippets inside your HTML <head> tag, in order.

  1. 1
    Copy the loader snippet
    This snippet installs a command-queue stub named Swake synchronously, then loads the full SDK asynchronously after the page has loaded.
    html
    <script>!function(w,d,i,s){function l(){if(!d.getElementById(i)){var f=d.getElementsByTagName(s)[0],e=d.createElement(s);e.type="text/javascript",e.async=!0,e.id=i,e.src="https://cdn.swake.io/sdk.js",f.parentNode.insertBefore(e,f)}}if("function"!=typeof w.Swake){var c=function(){c.q.push(Array.prototype.slice.call(arguments))};c.q=[],w.Swake=c,"complete"===d.readyState?l():w.attachEvent?w.attachEvent("onload",l):w.addEventListener("load",l,!1)}}(window,document,"swake-jssdk","script");</script>
    
  2. 2
    Add the identify call immediately after
    Replace the placeholder values with your project's API key and the authenticated user's details. This call is queued if the SDK hasn't finished loading yet — nothing is dropped.
    html
    <script>
      Swake('identify', {
        appID: 'ep_live_your_api_key',
        user: {
          id: 'user_123',
          email: 'jane@acme.com',
          name: 'Jane Doe',
        },
      });
    </script>
    

Order-independent calls: it is always safe to call Swake() before sdk.js finishes loading. The command queue holds every call and replays it once the script is ready.


Configuration

Swake('configure', options) is optional and can be called before or after identify. The most important option is portalUrl — set it once and data-swake-link anchors no longer need an href.

javascript
// Optional — call once, before or after identify().
Swake('configure', {
  portalUrl: 'https://quizly.swake.io', // your project's portal URL
  // apiBase: 'https://api.swake.io',   // override API URL (testing / self-hosted)
});
OptionDefaultDescription
portalUrl—The public portal URL for this project (e.g. https://quizly.swake.io or https://feedback.quizly.com). When set, data-swake-link anchors that have no href or href="#" use this URL automatically.
apiBasehttps://api.swake.ioOverride the API base URL. Useful for local development or self-hosted deployments.

Project-level portals: each project now has its own portal subdomain or custom domain. Set portalUrl to your project's URL (found in Project → Settings → Domains) so you don't need to hardcode it on every anchor — and so changing your portal domain later only requires one config update.


Identifying Users

Swake('identify', payload) is the single entry point for connecting your authenticated user to Swake.

typescript
interface IdentifyPayload {
  appID: string;              // Required — your project API key (ep_live_...)
  user: {
    id: string;               // Required — your internal user identifier
    email?: string;           // Strongly recommended — shown in the portal, used for notifications
    name?: string;            // Display name shown in the portal
    avatarURL?: string;       // Sent as device metadata — not persisted (see note below)
    created?: string;         // Sent as device metadata — not persisted (see note below)
    [key: string]: unknown;   // Any custom traits (plan, company, role, etc.)
  };
}

What happens internally

  1. 1
    appID and the user object are stored in memory for use by subsequent SDK calls.
  2. 2
    A POST /v1/sdk/identify request is sent to the Swake API, upserting the user record (email/name preserved if omitted; custom traits fully replaced).
  3. 3
    A delegated click listener is registered on document for <a> elements carrying the data-swake-link attribute (the selector is a[data-swake-link] — non-anchor elements are never intercepted).
  4. 4
    A success log is emitted: [Swake] Identified user: jane@acme.com

Field reference

FieldRequiredDescription
appIDRequiredYour project API key (ep_live_…). Found in Project → Settings → API Keys.
user.idRequiredYour internal user identifier. Must be stable — changing it creates a new user in Swake.
user.emailStrongly recommendedEmail address. Shown in the Swake portal and used for reply notifications. Not used to match the user — matching is always on user.id.
user.nameOptionalDisplay name shown in the Swake portal user list.
user.avatarURLOptionalSent to the API as device metadata. Not currently persisted — the portal avatar comes from the server-side image field instead (see note below).
user.createdOptionalSent to the API as device metadata alongside avatarURL. Not currently persisted.
user.*OptionalAny additional custom traits — plan, company, role, etc. Stored as customMetadata.

Avatars are set server-side, not by this SDK. avatarURL and created are sent inside the identify request's deviceMeta object, which POST /v1/sdk/identify does not currently read — so they are dropped. To show a real profile picture in the portal, pass a top-level image (a publicly reachable URL) when you call /v1/sdk/identify or /v1/sdk/portal-token from your own server. That is how the Portal Login flow supplies avatars.



Shareable Surveys

Every survey has a public shareable URL that works without any SDK integration on the respondent's device — ideal for email campaigns, QR codes, and in-app banners.

Domain setupSurvey URL format
Project subdomainhttps://{projectSlug}.swake.io/s/{surveySlug}
Custom domainhttps://feedback.acme.com/s/{surveySlug}

Survey slugs are auto-generated (6-character alphanumeric) when a survey is created. Find the shareable link in Dashboard → Installation → No-code tab. The shareable flag is on by default for every new survey; turning it off makes the public page return 404.

Use cases

Email campaigns
Embed a survey link in your product newsletter or post-purchase email.
QR codes
Print the survey URL as a QR code for physical locations or events.
In-app banners
Link directly to a survey from a modal, banner, or announcement bar.
Social & community
Share the survey link in a Slack channel, Discord server, or forum post.

Troubleshooting

SymptomCheck
No [Swake] logs in the consoleVerify the loader snippet is in the <head> of your page. Check the Network tab for a request to cdn.swake.io/sdk.js.
Identify API call failedMake sure appID and user.id are both present in the identify payload. Both fields are required.
Portal link not interceptedConfirm the element is an <a> tag with the data-swake-link attribute. identify() must have been called before the click.
Click does nothing — "[Swake] data-swake-link: no href…" in consoleThe anchor has no href and no portalUrl is configured. Either add href="https://your-project.swake.io" to the anchor, or call Swake('configure', { portalUrl: 'https://your-project.swake.io' }) once on the page.
CSP error: refused to load cdn.swake.ioAdd cdn.swake.io to your Content-Security-Policy script-src directive: script-src 'self' cdn.swake.io

Still stuck? Open a support ticket from the portal or email support@swake.io with your workspace slug and a description of the issue. Include any relevant console errors and Network tab screenshots.