Skip to main content
Headless — no built-in DOM injection, since you render your own UI. An API key skips CAPTCHA entirely.
client.form(id) scopes a client to one form so you can call .submit() (and .validate(), .upload()) on it repeatedly — client.forms.submit(id, data) is an equivalent one-off shorthand for the same thing. Not using Node.js specifically? The same createClient() / client.form(id).submit() pattern works identically in Solid.js, Alpine.js, and jQuery — or use the raw HTTP contract directly in any backend language.

CAPTCHA from Node.js

client.form(id).submit() never mounts or manages a CAPTCHA widget — that’s true from Node.js and equally true calling the same method from a browser (see Other Frontend Options for the browser case). The framework adapters (useRaykoiForm etc.) and submit.js are the two paths that own a widget’s lifecycle for you; the raw client, on any runtime, always resolves one of two ways:
  • Authenticating with an API key (as above) — the normal case. A secret key authenticates the request as server-to-server and skips the CAPTCHA gate entirely, same as it does for the Server Data API. Nothing to configure.
  • No API key — you must acquire and pass captchaToken yourself. In Node there’s no DOM to render a widget in at all, so this only makes sense when something else produced the token (a proxied browser submission, a headless-browser test harness, etc.):
This applies whether the form uses a self-managed provider (Turnstile/hCaptcha/reCAPTCHA) or Managed CAPTCHA — from the SDK’s side they’re indistinguishable, so the same two options above cover both.