Qrati SDK

The headless version of Qrati Connect

Your UI. The Qrati platform underneath.

Everything Qrati Connect's widget does, called directly instead of embedded — you own the UI. Uploads are live today; gallery, curation, and the rest of the platform are shipping the same way. See the roadmap →

Get started
import { createQrati } from '@qratilabs/qrati-sdk';

// runs in the browser — real byte-level progress via XHR
const qrati = createQrati(API_KEY, { uid, fname, lname });

const { contentId } = await qrati.upload({
  eventId,
  file, // from your own drop zone
  onProgress: ({ percent }) => setProgress(percent),
});
One API, every language: TypeScript Python Go PHP Java — it's a REST API underneath, so any language can call it today; these are planned official SDK wrappers.

Built for the UI you're already writing

No shadow DOM, no bundled framework, no styles to override. Just functions that return promises.

One call, not three

Direct-to-S3 upload is really create → PUT → complete. upload() hides all three behind a single await, with progress.

Runs anywhere JS does

Plain async functions, one package — a React effect, a Solid resource, a Svelte store, vanilla JS, or a Node backend job. No separate server build. See Browser & server.

Org-scoped API keys

One key per organization, safe to ship in your frontend bundle. Security comes from your domain allowlist — the same model your embedded widget already trusts.

Real upload progress

Byte-level progress in the browser via XHR, with a consistent callback whether you're running client-side or on the server.

TypeScript-first

Every request and response is a typed interface. Your editor tells you what a call needs before you hit the docs.

Escape hatches included

Want manual control? uploads.create/complete/fail/abort map 1:1 to the underlying API.

Three steps, no widget

  1. 1

    Install

    Add the package to your project.

    pnpm add @qratilabs/qrati-sdk
  2. 2

    Create a client

    Your org's API key, plus the end-user acting through your UI.

    const qrati = createQrati(API_KEY, { uid, fname, lname });
  3. 3

    Upload

    Hand it a file from your own drop zone, form, or file picker.

    const { contentId } = await qrati.upload({ eventId, file });
    100%

One platform, built headless piece by piece

Qrati Connect's widget does more than upload. The SDK is working through that same surface — headless, same operations, no widget.

Live now

  • Uploads — create, complete, fail, abort, plus the one-call upload()

Coming next

  • Event & folder discovery — list/search an org's public events
  • Gallery browsing — list, search, sort an event's content
  • My uploads — an end-user's own upload history
  • Reactions — emoji reactions on content
  • Curation — an approve/reject moderation queue
  • Leaderboard — score-ranked contest standings

Full roadmap, including what's deliberately not planned →

Read the docs

Getting started, the identity model, API-key security, and a full generated API reference.

Go to docs →