Skip to content

Repository files navigation

orqly logo

orqly

Build, test and simulate complex API workflows in a node-based visual editor.

Chain API calls as connected nodes, pipe any node's response into a later request, and watch the whole flow run step by step.

License: MIT Next.js TypeScript PRs welcome


Think Postman meets a flow builder: Create Customer → Share KYC → Create Payout becomes three wired nodes, and Create Payout reads {{nodes.Create Customer.response.body.id}} straight from the earlier call.

Features

  • Visual flow builder — each node is one API request (method, URL, headers, body). Drag to connect any node to any other; the target becomes a child, one level down. Delete a node and the graph re-levels itself.
  • Parallel runs — nodes on the same level execute concurrently; a failure marks everything downstream as skipped instead of aborting the run. All green earns confetti.
  • Response chaining{{env.API_KEY}} and {{nodes.<name>.response.body.…}} templates in URLs, headers and bodies, with a variable picker fed by real responses.
  • Import anything — paste a cURL command, or drop an OpenAPI 3, Swagger 2 or Postman collection; every endpoint becomes a node. An arrange step lets you set each request's level and drop the ones you don't want before building.
  • Workflow-wide env & headers — pick one active environment and one header set from the top bar; both apply to every node. Inline node headers override the set.
  • Pre-request scripts — a Postman-style script (with pm + CryptoJS) runs before each request; toggle it per workflow.
  • JSON body editor — syntax-highlighted, with {{template}} awareness.
  • Server-side proxy — requests execute from the server, so browser CORS never gets in the way.
  • Accounts & persistence — email OTP sign-in (+ optional Google / GitHub) via Better Auth; everything saves per user in Postgres.
  • Export / import — share a workflow with its referenced bodies and header sets as JSON.
  • Private beta mode — set one passcode and the whole app hides behind a waitlist page; invited testers enter the code, everyone else can join the list.

Quick start

cp .env.example .env      # fill in the required keys (see below)
npm install
npx drizzle-kit push      # create the database tables
npm run dev               # http://localhost:3000

Sign in with any email — without RESEND_API_KEY set, the OTP code is printed to the server console. A demo workflow targeting the built-in /api/echo endpoint is seeded on first sign-in.

How it works

  • Nodes & levels — a node's level is its row on the canvas. Level 1 runs after Start; level 2 after level 1, and so on. Connecting or dragging a node re-derives its level and re-lays out the graph.
  • Templating{{env.KEY}} pulls from the active environment; {{nodes.<label>.response.body.path.to.value}} pulls from an upstream node's last response. Resolved at run time.
  • Resources — request bodies, header sets and environments are saved once and referenced across nodes and workflows.
  • Execution — the runner walks the graph level by level, fires each level's nodes in parallel through /api/execute (the server proxy), and feeds responses back into the template context for downstream nodes. A failed node marks its descendants skipped; the rest of the flow keeps running.

Environment variables

All variables live in .env (never commit it — only .env.example is tracked); a few extra niche keys are documented inline in .env.example.

DATABASE_URL — required

Postgres connection string in the form postgresql://USER:PASSWORD@HOST:PORT/DATABASE. Get one from any of:

  • Local Docker (quickest for development):

    docker run -d --name orqly-pg \
      -e POSTGRES_PASSWORD=pg -e POSTGRES_DB=orqly \
      -p 5432:5432 postgres:16

    then use postgresql://postgres:pg@localhost:5432/orqly.

  • Locally installed Postgres — create a database (createdb orqly) and use your local credentials.

  • Hosted Postgres — create a free project on Neon, Supabase or Railway; each shows a ready-made postgresql://… URL. If the provider requires TLS, append ?sslmode=require.

After setting it, run npx drizzle-kit push once to create the tables.

BETTER_AUTH_SECRET — required

Random secret used to sign sessions. Generate it yourself:

npx @better-auth/cli@latest secret   # or: openssl rand -hex 32

Use a different secret per environment; rotating it signs every user out.

BETTER_AUTH_URL — required

The URL the app is served from, no trailing slash. Local: http://localhost:3000. Production: your deployed origin.

RESEND_API_KEY / RESEND_FROM — optional

Delivers sign-in OTP codes by email via Resend. Unset, codes are printed to the server console (dev only). RESEND_FROM needs a domain verified in Resend.

BETA_PASSCODE — optional

Set to put the whole app behind the waitlist: every page and API redirects to /waitlist until the visitor enters this passcode (share it with beta testers). Unset = the app is open (local dev, self-hosting). NEXT_PUBLIC_DISCORD_URL / NEXT_PUBLIC_X_URL add social links to the waitlist success screen.

GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET — optional

Enables "Continue with Google" (hidden while unset; email/password works without them). From the Google Cloud Console:

  1. Create/select a project at console.cloud.google.com.
  2. APIs & Services → OAuth consent screen: External, add yourself as a test user.
  3. Credentials → Create credentials → OAuth client ID → Web application:
    • Authorized origin: http://localhost:3000 (+ your production origin)
    • Redirect URI: http://localhost:3000/api/auth/callback/google (+ production)
  4. Copy the Client ID and secret into .env, then restart the dev server.

GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET — optional

Enables "Continue with GitHub". Create an OAuth App at github.com/settings/developers with redirect URI {BETTER_AUTH_URL}/api/auth/callback/github.

EXECUTE_BLOCK_PRIVATE_IPS — optional, recommended in production

Set to 1 to make the request proxy (/api/execute) refuse URLs pointing at loopback/private addresses (localhost, 10.x, 192.168.x, …), so users can't probe your internal network. Leave unset in local dev — the seeded demo calls the app's own /api/echo, which a private-IP block would reject.

Stack

Next.js (App Router) · TypeScript · Tailwind CSS · React Flow (@xyflow/react) · zustand · Better Auth · Drizzle ORM · Postgres

Project layout

src/
  app/            Next.js routes — pages, auth, /api/execute proxy, /api/data CRUD
  components/     canvas (React Flow nodes), sidebar, inspector, wizard, shared UI
  lib/            store (zustand), runner, interpolation, importers (curl/openapi/postman)
  db/             Drizzle schema

Contributing

Issues and PRs welcome.

npm run lint          # eslint
npx tsc --noEmit      # type-check

Keep changes minimal and typed; npx drizzle-kit push after any schema change. Open an issue first for larger features.

License

MIT © Chakravarti Avinit

Releases

Packages

Contributors

Languages