GoIdentity Public SDK Docs
Embed GoIdentity verification into a customer-facing website while keeping backend credentials private.
Before You Start
To complete a Public SDK integration end-to-end you need the following. Gather all of these first — most integration friction comes from missing one of them later.
| Requirement | Purpose |
|---|---|
| GoIdentity dashboard account | Manage SDK integrations, view KYC results. |
SDK public key (gidsk_…) | Used by frontend code. Safe to expose in the browser. |
Backend client key + secret (gidck_…, gidcs_…) | Used only on your server to create session tokens. Never expose in the browser. |
| Allowed domain(s) | Whitelist where the SDK can be embedded. Prevents unauthorized embeds. |
| Sandbox/dev environment access | Run integration smoke tests with mock identity data. |
Architecture
The Public SDK splits work between three actors so that identity-grade secrets never reach the browser:
GoIdentity Public SDK – Simple Flow
How the browser, customer backend, and GoIdentity API work together
What runs where
- Customer browser: public SDK key + short-lived session token + the GoIdentity iframe.
- Customer backend: client key + client secret, plus a
/sessionroute that exchanges them for a session token. - GoIdentity API: validates the client secret, mints session tokens, and hosts the verification flow.
gidcs_… anywhere in page source, in a JS bundle, or in network requests originating from the browser, stop and rotate the credential.Quickstart
- Create an SDK integration in the GoIdentity dashboard.
- Add your allowed domain(s), including
localhostfor local testing. - Copy the public SDK key (
gidsk_…) and the backend client key + secret. - Store the client secret in your backend secrets manager. It must never appear in frontend code.
- Add the script include to the page that will host the verification form.
- Implement a
/sessionroute on your backend that exchangesgidck_+gidcs_for a session token. - Mount the SDK on the page using
sdkKey+sessionToken+ your event handlers. - Wire
onCompleteto forward the result to your backend so you can persist the KYC outcome. - Smoke-test in sandbox, then add production domains + go live.
Integration
Script Include
Add the SDK script in the page <head> or before </body>:
<script src="https://dashboard.dev.goidentity.com/goidentity-sdk.js"></script>Mount Snippet
Mount the verification form where it should appear in the page:
<div id="goidentity-verify-person"></div>
<script>
GoIdentitySDK.mountVerifyPerson("#goidentity-verify-person", {
sdkKey: "gidsk_PUBLIC_SDK_KEY",
sessionToken: "gidst_SESSION_TOKEN_FROM_YOUR_BACKEND",
width: "100%",
minHeight: "500px",
// Optional. Pre-filled fields are hidden. If every required field is
// pre-filled and valid, the form auto-submits. See "Prefill & Auto-submit".
prefill: {
firstName: "Jane",
lastName: "Doe",
dateOfBirth: "1990-04-12",
email: "jane@example.com",
contactNumber: "+447700900123",
countryCode: "GB",
},
onReady: () => console.log("SDK ready"),
onComplete: (payload) => console.log("KYC complete", payload.kycId),
onError: (err) => console.error(err.code, err.message),
});
</script>End-to-end Flow
Customer frontend page
-> loads goidentity-sdk.js
-> asks customer backend for session token
-> mounts GoIdentity iframe
-> iframe loads GoIdentity verification form
-> SDK fires onComplete when user finishes
-> frontend forwards result to customer backendBackend Session Token
The session token is the bridge between the browser and the GoIdentity API. Your backend mints it; the browser uses it once.
Properties
| Property | Value |
|---|---|
| Default TTL | 10 minutes from creation (see ttlSeconds in the response). |
| One-time-use | Yes — consumed by /public/sdk/verify-a-person when the KYC request is created. /public/sdk/resolve validates without consuming. |
| SDK key scope | Bound to the sdkKey you passed in the create call. Cannot be used with a different SDK key. |
| External reference | Optional. Carried through to the KYC request so you can correlate it back to your own user / order ID. |
| If expired or reused | Form fails to load with session_token_invalid. Backend must mint a fresh token. Frontend should refetch on demand, not on a timer. |
Create a session token
POST https://api.dev.goidentity.com/public/sdk/session
X-GoIdentity-Client-Key: gidck_CLIENT_KEY_ID
X-GoIdentity-Client-Secret: gidcs_CLIENT_SECRET
Content-Type: application/json
{
"sdkKey": "gidsk_PUBLIC_SDK_KEY",
"externalReference": "optional-user-or-order-id"
}Response
{
"sessionToken": "gidst_SESSION_TOKEN",
"expiresOn": "2026-04-29T12:00:00Z",
"ttlSeconds": 600
}Error response
{
"error": {
"code": "session_token_invalid",
"message": "Session token is missing, expired, already used, or scoped to a different SDK key."
}
}X-GoIdentity-Client-Secret in a browser request, in serverless logs, or in error messages. Treat it like a database password.Configuration
| Parameter | Required | Default | Description |
|---|---|---|---|
sdkKey | Yes | None | Public SDK key from the GoIdentity dashboard. Safe to expose in browser code. |
sessionToken | Yes | None | Short-lived token minted by your backend. Required to load and submit the SDK form. |
width | No | 100% | Iframe width. Accepts CSS values or numbers. |
height | No | auto | Iframe height. auto enables responsive resizing. |
minHeight | No | 500px with auto height | Minimum iframe height. |
prefill | No | None | Object of known values to populate into the form. Pre-filled fields that pass validation are hidden from the user. If all required fields are pre-filled and valid, the form auto-submits. See Prefill & Auto-submit. |
Responsive height
height: "auto",
minHeight: "500px"Fixed height
height: "720px",
minHeight: "0px"Prefill & Auto-submit
If your application already knows some of the user’s identity details, pass them via the prefill option on mountVerifyPerson. Fields that arrive pre-filledand pass validation are hidden from the user. If every required field is pre-filled and valid, the SDK auto-submits the verification request and the user only sees a brief Verifying… state.
Example
GoIdentitySDK.mountVerifyPerson("#goidentity-verify-person", {
sdkKey,
sessionToken,
width: "100%",
minHeight: "500px",
prefill: {
// Name — pass any of these. See "Name mode adaptation" below.
firstName: "Jane",
lastName: "Doe",
// fullName: "Jane Doe",
// title: "Ms",
// Other supported fields. Any omitted field stays visible.
dateOfBirth: "1990-04-12", // ISO YYYY-MM-DD
email: "jane@example.com",
contactNumber: "+447700900123", // E.164 with country code
countryCode: "GB", // ISO 3166-1 alpha-2
},
});Supported fields
| Key | Type | Example | Notes |
|---|---|---|---|
firstName | string | "Jane" | Used in split and titleSplit name modes. |
lastName | string | "Doe" | Used in split and titleSplit name modes. |
fullName | string | "Jane Doe" | Used directly in single name mode. |
title | string | "Ms" | Only used in titleSplit mode. Accepted values: Mr, Mrs, Ms, Miss, Mx, Dr. |
dateOfBirth | string | "1990-04-12" | ISO 8601 calendar date (YYYY-MM-DD). Must be in the past. |
email | string | "jane@example.com" | Standard email format. |
contactNumber | string | "+447700900123" | E.164 format including the leading + and country code. |
countryCode | string | "GB" | ISO 3166-1 alpha-2 country code (uppercase). |
Name mode adaptation
The form’s name layout is configured in the Form Studio (Single, First + Last, or Title + First + Last). The SDK adapts prefill values to whatever mode is active:
- Single mode +
firstName/lastName: joined with a space and used asfullName. - Split / Title-split mode + only
fullName: split on the first whitespace. The first token becomesfirstName, the rest becomeslastName. For best results, passfirstNameandlastNameexplicitly when you know them. - Title-split mode +
title: used as the salutation dropdown value. Ignored in the other modes.
Auto-submit behavior
- Auto-submit fires only when every required field (
fullName/firstName+lastName,dateOfBirth,email,contactNumber,countryCode) is pre-filledand passes validation. - The user sees a brief
Verifying…spinner instead of an empty form, then the same success screen as a manual submission. - If the auto-submit request fails (network error, server rejection), the form re-appears with the pre-filled values populated so the user can correct anything and submit manually.
- If any pre-filled value fails validation (e.g. malformed email, future
dateOfBirth), that field renders with its standard validation error and the user is asked to correct it. Other valid pre-fills stay hidden. Auto-submit does not fire.
Security
postMessage, never via the URL. PII does not appear in browser history, server access logs, or the iframe’s document.referrer. The GoIdentity API still validates every submission server-side regardless of prefill — pre-filling does not bypass any verification logic.Domain Allowlist
The domain allowlist prevents an SDK key from being used on unauthorized websites. Configure it on the SDK integration page in the dashboard.
Allowed formats
example.com
app.example.com
*.example.com
localhost
127.0.0.1*.example.com allows example.com, app.example.com, and client.example.com.
| Mistake | Fix |
|---|---|
Adding https://app.example.com/path | Add app.example.com only. |
Testing locally without localhost | Add localhost to the allowed domains. |
Allowing only www.example.com while embedding on app.example.com | Add the exact embedding domain or use *.example.com. |
| Using a token from one SDK key with another SDK key | Create a session token for the same sdkKey used by the frontend. |
The iframe page sends its browser document.referrer to the API. The API validates that referrer domain against the SDK integration allowlist.
Code Examples
Frontend
<!doctype html>
<html>
<head>
<script src="https://dashboard.dev.goidentity.com/goidentity-sdk.js"></script>
</head>
<body>
<div id="goidentity-verify-person"></div>
<script>
async function start() {
const r = await fetch("/api/goidentity-session", { method: "POST" });
const { sdkKey, sessionToken } = await r.json();
GoIdentitySDK.mountVerifyPerson("#goidentity-verify-person", {
sdkKey,
sessionToken,
width: "100%",
minHeight: "500px",
onComplete: (payload) => console.log("KYC complete", payload.kycId),
onError: (err) => console.error(err.code, err.message),
});
}
start();
</script>
</body>
</html>Backend session endpoint
// Node / Express backend route
import express from "express";
const app = express();
app.use(express.json());
app.post("/api/goidentity-session", async (req, res) => {
const r = await fetch(
"https://api.dev.goidentity.com/public/sdk/session",
{
method: "POST",
headers: {
"X-GoIdentity-Client-Key": process.env.GOIDENTITY_CLIENT_KEY!,
"X-GoIdentity-Client-Secret": process.env.GOIDENTITY_CLIENT_SECRET!,
"Content-Type": "application/json",
},
body: JSON.stringify({
sdkKey: process.env.GOIDENTITY_SDK_KEY,
externalReference: req.user?.id, // optional
}),
},
);
if (!r.ok) return res.status(502).json({ error: "session_create_failed" });
const { sessionToken } = await r.json();
// Only return the public key + short-lived token to the browser.
res.json({
sdkKey: process.env.GOIDENTITY_SDK_KEY,
sessionToken,
});
});Layout variants
GoIdentitySDK.mountVerifyPerson("#goidentity-verify-person", {
sdkKey,
sessionToken,
width: "100%",
minHeight: "500px",
});Environments
invalid_sdk_key.| Environment | Purpose | SDK script | API base URL |
|---|---|---|---|
| Sandbox / Dev | Testing with mock data, no real verification. | https://dashboard.dev.goidentity.com/goidentity-sdk.js | https://api.dev.goidentity.com |
| Production | Real customer verification, billed. | https://dashboard.goidentity.com/goidentity-sdk.js | https://api.goidentity.com |
Troubleshooting
Common integration issues and the fastest way to diagnose them. Pair this with browser DevTools — every SDK request is visible in the Network tab.
| Problem | Likely cause | Fix |
|---|---|---|
| SDK does not load | Script URL blocked by CSP, network, or wrong environment. | Check the Network tab for a 200 on goidentity-sdk.js. Add the script src to your script-src CSP. |
| Form shows "unavailable" | /public/sdk/resolve failed: bad sdkKey, bad token, or domain not allowed. | Check the response body in DevTools. The error.code tells you which. |
session_token_invalid | Token expired (default TTL 10 min), already used, or scoped to a different SDK key. | Mint a fresh token on every page load — do not cache it client-side. |
domain_not_allowed | Embedding page domain not in the integration allowlist. | Add the exact domain (no scheme, no path) in the SDK integration settings. |
| iframe blocked / X-Frame-Options | Parent page has a restrictive frame-ancestors CSP. | Add the GoIdentity dashboard origin to your frame-src CSP. |
| Verification stuck on a step | Missing workflow configuration in the SDK integration (services / questionnaire). | Open the SDK integration in the dashboard and confirm at least one verification service is enabled. |
onComplete never fires | Callback was passed as null or attached after mount. | Pass callbacks in the same options object as mountVerifyPerson. |
Error Reference
| Code | Meaning | Fix |
|---|---|---|
invalid_sdk_key | The sdkKey does not match an active SDK integration. | Confirm the public SDK key and integration status. |
domain_not_allowed | The embedding page domain is not in the allowlist. | Add the domain in the SDK integration and retry. |
session_token_invalid | Token missing, expired, already used, or scoped to a different SDK key. | Ask your backend for a fresh session token. |
session_create_failed | Backend call to /public/sdk/session failed (bad client credentials). | Verify X-GoIdentity-Client-Key and X-GoIdentity-Client-Secret in your secrets manager. |
form_unavailable | Resolve failed before the form could load. | Check sdkKey, sessionToken, and allowed domains. |
iframe_height_error | Parent layout constraining the iframe. | Use height: "auto" with minHeight, or set a fixed height. |
cors_blocked | API or dashboard origin blocked or misconfigured. | Use the correct environment URLs and check browser network errors. |
Go Live Checklist
- Production SDK key created.
- Backend client key and secret stored securely (secrets manager, never in code).
- Session token endpoint implemented on your backend.
- Domain allowlist verified for production domains.
- Embedded form tested on the final production domain.
- Responsive and fixed-height behavior checked on desktop and mobile.
- Error handling added for token creation failure.
onErrorwired up; user-visible error message defined.- Verified the client secret does not appear in browser source, JS bundle, or network requests.
- Support or monitoring contact confirmed.