Skip to Content
DocsCloud OSOrbit Forms

Orbit Forms

Orbit Forms is your self-hosted Google Forms / TypeForm replacement. Build a form in a drag-drop builder, share a clean public URL at /f/<token>, and watch responses land as rows in an Orbit Sheet of your choice. File-upload fields bridge to Orbit Drive, so the entire submission stays inside your Workspace.

This is the fourth app in Quazzar Workspace, alongside Drive, Mail, and Calendar.

What you get

  • Drag-drop builder at /forms. Seven field types: short text, long text, email, number, single choice, multi choice, file upload.
  • Public submit URL at /f/<token> — clean, shell-less page rendered without the Quazzar dock or sidebar.
  • Submissions become Sheet rows — pick a destination Orbit Sheet (or create one); each submit appends a row in field-order.
  • File uploads bridge to Drive — a dedicated form-owned Drive folder receives the files, the Sheet cell value is a Drive share URL.
  • Anonymous-friendly by default — turn on require_login for internal-only forms.
  • Anti-abuse: 30 submissions per IP per form per hour by default, raise/lower per form on Pro+. Optional hCaptcha (operator supplies HCAPTCHA_SECRET).

Building a form

  1. Open Forms in the dock (Work group, clipboard icon) or navigate to /forms.
  2. Click New form. Give it a title and description.
  3. Build tab — drag a field type from the palette into the field stack on the right (or click to append). Click any field to inline-edit:
    • Required toggle.
    • Placeholder for text/email/long-text.
    • Max length for long text.
    • Min / max for number.
    • Options list (one per line) for single/multi choice.
    • Max size MB / accept mime list for file uploads.
  4. Preview tab — submit through a sandboxed preview that echoes the cells; nothing writes to the destination Sheet here.
  5. Share tab — set the destination Sheet ID + tab name, the upload-folder Drive ID (only shown when a file field exists), the require_login toggle, and the captcha toggle. Copy the public URL or grab the embed snippet.
  6. Click Publish. The header row of the destination Sheet syncs to the current schema labels in field order; the form is now live at /f/<token>.

Publishing model

Editing a published form mutates in place — there’s no schema versioning. Old responses keep their values aligned with the labels they were submitted under (the labels become Sheet column headers on first publish). Renaming a label after publish does NOT rename the Sheet column header; treat label changes as additive.

File uploads

When a field of type file is in the schema, Orbit Forms auto-creates an upload folder in your Drive (named Form: <title> under /Forms/) the first time a submission with a file lands. Each upload writes the file to that folder; the Sheet row’s cell for that field is a Drive share link.

  • The form owner controls the folder — you can move it, rename it, share it externally with a Drive share link.
  • Per-field max_size_mb is enforced server-side — clients that try to upload a larger file are rejected before the file ever reaches Drive.
  • accept is a list of MIME types (application/pdf, image/*, …). Strict matching only on type/subtype; image/* matches any image/....

Anti-abuse

  • Rate limit: 30 submits / IP / form / hour (default). Lowered/raised in form settings (Pro+ for non-default values). Persisted server-side, survives restarts.
  • require_login: flip the public submit endpoint to require an authenticated Quazzar session — handy for internal employee forms.
  • hCaptcha: enable the toggle in the Share tab. Operator must set HCAPTCHA_SECRET env var. If the toggle is on but no secret is configured, the OS logs a warning and accepts submissions (better than bricking a public form).

Plans

TierFormsFile uploadsCaptcha
Free (Community)1 active form
Prounlimited
Team / Enterpriseunlimited

Surfaced in /api/license/orbit-features as orbit_forms, orbit_form_uploads, orbit_form_captcha. Hitting a paid limit triggers the standard OrbitUpgradeDialog.

API surface

Authenticated owner endpoints:

  • GET /api/forms — list owned forms.
  • POST /api/forms — create.
  • GET /api/forms/{id} — fetch (with schema).
  • PUT /api/forms/{id} — update title/description/schema/target.
  • POST /api/forms/{id}/publish — flip is_published, sync header row in destination Sheet.
  • DELETE /api/forms/{id} — delete.
  • GET /api/forms/{id}/export.csv — CSV export of the destination Sheet.

Public peers (no auth required by default):

  • POST /forms/{public_token}/submit — multipart/form-data or urlencoded.
  • GET /f/{public_token} — HTML shell with the form schema embedded as a JSON island.

Limitations & roadmap

  • No branching / conditional logic — TypeForm-style “show field X only when Y answers Z” is a v2 surface.
  • No payments / Stripe blocks — Pro+ later.
  • Destination Sheet picker is currently a Sheet-ID + tab text input, not a visual picker dialog. The wire format is final; the UI swap is cosmetic and ships in 0.7.5.
  • No response-charts dashboard yet — for now use the Sheet’s pivot/chart surface. A dedicated Responses dashboard ships alongside the picker swap.