Skip to main content
Raykoi is headless form infrastructure. You bring the UI — any HTML, any framework, no framework at all — and Raykoi owns everything that happens after someone hits submit: validation, spam protection, storage, file uploads, and analytics. There’s no hosted form builder to fight with and no iframe to embed. A Raykoi form is just a URL your own markup posts to.

Quickstart

Get a real submission flowing in under five minutes.

Integrations

Copy-paste code for React, Vue, Svelte, Angular, Node.js, plain HTML, and more.

CAPTCHA Setup

Get a site key from Turnstile, hCaptcha, or reCAPTCHA and connect it.

API Reference

Every public endpoint, request/response shapes, and rate limits.

How it fits together

Four layers, each with one job:
  • UI — entirely yours. Raykoi never renders your form.
  • SDK@raykoi/sdk (React/Vue/Svelte/Angular adapters, or plain JS) and submit.js (a zero-dependency runtime for raw HTML) both talk to the same Forms API underneath. Pick whichever matches your stack; the wire contract never changes.
  • Forms API — the public, mostly-unauthenticated surface a browser talks to directly: fetch a form’s schema, validate data, submit, upload a file, track an analytics event.
  • Server / Admin API — a separate, secret-key-authenticated surface for your own backend to read submissions, analytics, and files. Never used by browsers.

What Raykoi does not do

  • No hard-required anti-replay token. Every submission path — including a plain <form method="POST"> with JavaScript disabled entirely — hits the exact same public endpoint with no extra round-trip required first. Spam protection is CAPTCHA, honeypot, rate limiting, and abuse detection — signals that provide real, independent value, not a token that only proves a client made a GET request.
  • No opinion on your design system. The Basic HTML runtime writes plain, unstyled markup with stable class hooks (.raykoi-message, .raykoi-field-error) — you style it. The framework adapters (useRaykoiForm) return raw state (submitting, fieldErrors, status) — you render it.
  • No lock-in on file storage. Uploads go straight to storage via a short-lived signed URL; your server never proxies file bytes unless you want it to.
Every code sample in this documentation is checked against the live server and SDK source — not written from memory and left to rot. If something here stops matching reality, that’s a bug in the docs, not intentional drift.

Next step

Head to the Quickstart — you’ll have a form accepting real submissions before you’ve read this far again.