Most tools that let you chain API calls together (Postman, Insomnia, a pile of curl in a bash script) solve the problem by adding a script layer on top of your requests. You write pm.environment.set('token', ...), manage an environment file, and now your test flow lives in a tool that knows nothing about your actual codebase or OpenAPI contract.
We built Enlace to avoid that layer entirely: no scripts, no environment files, no server component executing anything on your behalf. Your OpenAPI document becomes a canvas. You wire response fields into later request parameters. The chain runs in the browser, straight at your API.
The problem Enlace is for
Swagger UI's "Try it out" is excellent for one call. The pain shows up on multi-step flows:
- Create a resource
- Take an id or token from the response
- Call two more endpoints that need that value
- Maybe run independent branches concurrently before a join step
People usually bounce to Postman env vars, throwaway scripts, or a half-maintained collection that drifts from the real OpenAPI spec. Enlace keeps the contract as the source of truth and makes the chain a first-class object.
Quick start (adapters are thin on purpose)
Pick the adapter for your stack. Each one does the same two jobs: serve the UI bundle and serve your OpenAPI document. Nothing else.
Most teams already generate that document from the framework (FastAPI's built-in OpenAPI, @nestjs/swagger, swagger-jsdoc, Swashbuckle, springdoc, and so on). Hand Enlace that same object. You do not need a separate openapi.json on disk unless that file is already your source of truth.
FastAPI (use the spec FastAPI already builds from your routes):
pip install enlace-fastapi
from fastapi import FastAPI
from enlace_fastapi import enlace
app = FastAPI(title="My API", version="1.0.0")
# ... register your routes first ...
app.include_router(enlace(spec=app.openapi()), prefix="/enlace")
Call app.openapi() after routes are registered. Your existing /docs or /redoc keep working; Enlace is just another consumer of the same document.
NestJS (use the document from @nestjs/swagger):
npm install @get-enlace/nest
// app.module.ts
import { Module } from '@nestjs/common';
import { EnlaceModule } from '@get-enlace/nest';
@Module({ imports: [EnlaceModule] })
export class AppModule {}
// main.ts
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { EnlaceModule } from '@get-enlace/nest';
import { AppModule } from './app.module';
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('My API')
.setVersion('1.0.0')
.build();
EnlaceModule.setSpec(app, SwaggerModule.createDocument(app, config));
await app.listen(4000);
Express (pass whatever you already generate, e.g. swagger-jsdoc):
npm install @get-enlace/express
import express from 'express';
import swaggerJsdoc from 'swagger-jsdoc';
import { enlace } from '@get-enlace/express';
const spec = swaggerJsdoc({
definition: {
openapi: '3.0.3',
info: { title: 'My API', version: '1.0.0' },
},
apis: ['./routes/*.js'],
});
const app = express();
app.use('/enlace', enlace({ spec }));
If the docs live in a file (or are hand-written): a checked-in openapi.json / .yaml, or a URL that already serves the document — pass that path or URL as spec instead (Nest: EnlaceModule.forRoot({ spec: './openapi.json' })). Same mount; different source.
Also available today: ASP.NET Core (AddEnlace() / UseEnlace(), typically beside Swashbuckle) and Spring Boot (enlace-spring-boot-starter, typically beside springdoc). Docs: https://get-enlace.github.io/
Live demo (served by the FastAPI adapter): https://enlace-fastapi.onrender.com/enlace/
Wiring calls without scripts
Drop endpoints from your OpenAPI doc onto the canvas, fill in what you need, and connect a field from one response into the next request. Mapping uses JSONPath with autocomplete from the last real response, so you are pointing at data you already saw, not guessing field names from memory.
Independent branches run concurrently; dependent steps wait. Details on running and reading results: Run a chain.
Features worth knowing about
Debug: Arm a breakpoint on a connector (double-click the solid arrow), then use Debug instead of Run. Execution pauses so you can inspect the request before it goes out. Run ignores breakpoints on purpose, so you can leave them armed while still doing full runs.
Docs: Debug a chain
Rerun failed: When a chain fails partway, Rerun failed resumes from what did not finish and reuses successful prior results instead of re-firing the whole graph. Debug failed does the same resume with breakpoints honored.
Docs: Rerun after a failure
Autosave: This browser remembers your last session on its own (canvas layout and related state), so a refresh does not wipe the chain you were building.
Docs: Autosave
Export / Import: From Settings, export a .enlace file to keep a copy, hand to a teammate, or check into a repo. Partial export keeps credential shape but strips secrets; full-credential export is always password-encrypted. Import brings the workflow back onto the canvas.
Docs: Save and share a workflow
Concurrent branches, no scheduler service
Independent steps that do not depend on each other fire at the same time, not in a fake "one after another" order. Enlace walks the dependency graph, groups ready nodes into levels, and runs each level concurrently in the browser. No workers, no queue, no external scheduler.
More detail: Run a chain.
Why nothing is proxied
Two HTTP relationships in Enlace never cross:
- Browser ↔ adapter: UI assets + OpenAPI document only
- Browser ↔ your API: the actual execution calls
There is no server-side execution engine anywhere in the project. The adapters (FastAPI, Express, NestJS, ASP.NET Core, Spring Boot) are thin and symmetric on purpose. They do not proxy your traffic.
So a bearer token you paste into Enlace lives in browser memory for that tab's session and nowhere else: not in adapter logs, not on disk, not in transit to a third party. Same trust model as Swagger UI's "Try it out," extended across a chain instead of one call.
Where it stands
Enlace is at 0.0.9, early beta. Adapters available today: FastAPI, Express, NestJS, ASP.NET Core, and Spring Boot.
- Live demo: https://enlace-fastapi.onrender.com/enlace/
- Docs: https://get-enlace.github.io/
- Anchor repo: https://github.com/get-enlace/enlace
Try it on a real API and tell us what works, what does not, and what you want next. Feature requests are welcome: Feature requests.
Give a Star to the repo if you find it useful.
Top comments (0)