# apiblaze

CLI for [APIblaze](https://apiblaze.com) — chat with your APIs, run them as serverless proxies, and let your customers self-serve keys, users & groups from your own site.

---

## Install

```bash
npx apiblaze --help        # run without installing
npm install -g apiblaze    # or install globally
```

Requires Node.js 18+.

## Quick start

The easiest way is to just chat with it:

```bash
npx apiblaze agent
```

> Talk in plain English — "make an API for httpbin.org", "rate-limit it to 50/sec",
> "give me a key". It does the work and shows what each step costs.

Prefer commands? A few one-liners:

```bash
# Chat with your API
npx apiblaze apichat --openapi https://apiblaze.com/pokeapi_openapi.yaml

# Make an API in one line — no account needed (prints a claim URL)
npx apiblaze create --target https://api.example.com

# Or build it straight from an OpenAPI spec — a URL or a local file.
# The routes, the API version and one environment per `servers` entry all come from the spec.
npx apiblaze create --openapi https://petstore3.swagger.io/api/v3/openapi.json

# Configure how your backend is accessed through the proxy
npx apiblaze config

# Configure who accesses your backend through the proxy
npx apiblaze tenant

# Access your localhost through a proxied URL
npx apiblaze dev 3000

# Route a Next.js app's outbound fetch() through APIblaze
npx apiblaze sidecar

# Sign in to manage APIs under your team
npx apiblaze login
```

## Embeddable widgets (React)

Let your customers self-serve from **your** site — **API keys** (`<ApiKeyWidget/>`) and
**users, groups & admins** (`<UsersGroupsWidget/>`). Each is one server route holding your
**Widget key** (Dashboard → Developers) plus one component; the browser only ever talks to
your backend — no secrets in the client. One `getUser` maps your session
(`{ tenant, userId, email }`); **both widgets share the same key**.

```ts
// app/api/apiblaze/keys/route.ts    → <ApiKeyWidget/>
import { createApiblazeKeys } from 'apiblaze/server';
const keys = createApiblazeKeys({ cpKey: process.env.APIBLAZE_CP_KEY!, getUser });
export const GET = keys.handler, POST = keys.handler;

// app/api/apiblaze/groups/route.ts  → <UsersGroupsWidget/>   (same key)
import { createApiblazeGroups } from 'apiblaze/server';
const groups = createApiblazeGroups({ cpKey: process.env.APIBLAZE_CP_KEY!, getUser });
export const GET = groups.handler, POST = groups.handler;
```

```tsx
'use client';
import { ApiKeyWidget, UsersGroupsWidget } from 'apiblaze/react';

<ApiKeyWidget theme={{ accent: '#7C3AED' }} />;        // keys: create · rotate · revoke
<UsersGroupsWidget theme={{ accent: '#7C3AED' }} />;   // users · nested groups · co-admins · seen-in-traffic
```

Every color and font is a `theme` token — white-label to any brand. Eligibility and admin
rights are decided on **your** server from your session, never the browser.

## Help

```bash
apiblaze --help            # all commands
apiblaze help create       # help for one command
apiblaze domain --help     # subcommands of a group (domain/tenant/key/spec)
```

Add `--verbose` (or `-v`) to **any** command to print the exact series of API
calls it makes — as copy-pasteable `curl` you could run yourself with your own
login token, plus the underlying admin-api leaf each one drives:

```bash
apiblaze throttle myapi --rate 50 --verbose
```

## Commands

### Chat

| Command | What it does |
|---|---|
| `apiblaze agent` | Chat about anything — create, configure, and inspect your APIs |
| `apiblaze agent openapi <project>` | Chat to build your API spec from real traffic |
| `apiblaze agent authz <project>` | Chat to design and turn on access rules |
| `apiblaze agent mcp <project>` | Chat to build an MCP server for your API |

Every chat turn shows its cost.

### Setup

| Command | What it does |
|---|---|
| `apiblaze create --target <url>` | Make an API from a backend (no account needed) |
| `apiblaze create --openapi <file\|url>` | Make an API from an OpenAPI spec — a local file or a spec URL (`--openapispec` is the same flag) |
| `apiblaze sidecar` | Route a Next.js app's external `fetch()` calls through APIblaze (one command) |
| `apiblaze dev [port]` | Put your localhost behind a public URL |
| `apiblaze login` / `logout` | Sign in / out (logout asks producer or consumer) |
| `apiblaze whoami` | Who am I — both Producer and Consumer |
| `apiblaze team [name]` | Switch team |
| `apiblaze claim [code]` | Claim an API you made before signing in |

### Producer — your APIs

| Command | What it does |
|---|---|
| `apiblaze projects` | List your APIs |
| `apiblaze delete <project>` | Delete it and everything under it (asks first) |
| `apiblaze domain add <project> --domain <host>` | Add your own domain (shows the DNS records to set) |
| `apiblaze domain status / list / rm <project>` | Check / list / remove custom domains |
| `apiblaze domain set-base <project> [--env <e>]` | Pick which version/env your main URL serves |
| `apiblaze tenant create --name <name>` | Create a tenant (a separate group of your API's users) |
| `apiblaze tenant attach <project> --tenant <slug>` | Give a proxy its own set of users |
| `apiblaze tenant cors --tenant <slug> --origins <a,b>` | Set which websites can call it |
| `apiblaze tenant list / delete <slug>` | List / delete tenants |

### Producer — users, groups & authorization

| Command | What it does |
|---|---|
| `apiblaze group create / list / delete <name>` | Manage a tenant's groups (also `<UsersGroupsWidget/>`) |
| `apiblaze group add-user / remove-user <user> <group>` | Put a user in a group (or take them out) |
| `apiblaze group add-group / remove-group <child> <parent>` | Nest a group inside a group |
| `apiblaze rule "<plain english>" <project> [--enforce]` | Author an object-level access rule in one shot (shadow, then `--enforce`) |
| `apiblaze agent authz <project>` | Design & turn on authorization interactively (chat) |

### Producer — change a proxy's config

| Command | What it does |
|---|---|
| `apiblaze target <project> --url <url> [--env <e>]` | Change where it forwards requests |
| `apiblaze throttle <project> [--rate n] [--quota n] [--period daily\|weekly\|monthly]` | Set rate limits and quotas |
| `apiblaze rename <project> --display-name <name>` | Rename it |
| `apiblaze spec get <project>` | Print its OpenAPI spec |
| `apiblaze spec set <project> --file <path>` | Replace its OpenAPI spec from a file |

> Every command in these two sections accepts `--verbose` (see the equivalent API
> calls), plus `--team`, `--apiversion`, and `--json`.

### Consumer — use an API

Log in to one of your tenants' portals **as a consumer** — handy for testing auth
and keys end-to-end. This is a separate identity from your producer login; `whoami`
shows both, and `logout` asks which to drop.

| Command | What it does |
|---|---|
| `apiblaze consumer login` | Pick a tenant and log in to its portal (device flow in your browser) |
| `apiblaze consumer tokens` | Show your consumer access / refresh / id tokens |
| `apiblaze consumer apikeys` | List your API keys (reveals expiring ones in clear), then offer to create one |

> A standalone consumer (no producer account) can log in with
> `apiblaze consumer login --tenant <slug> --client <appClientId>`.
>
> Advanced: `apiblaze apikeys` manages producer control-plane keys for scripting.

## How it works

`apiblaze dev` automatically:

1. Fetches your APIblaze projects that target `localhost` (or other internal targets)
2. Registers a temporary dev tunnel with APIblaze
3. Opens a secure connection and forwards incoming requests to your local server
4. Streams live traffic logs to your terminal in real time

On Ctrl+C the tunnel is cleanly deregistered.

## Sidecar — proxy a Next.js app's egress

`apiblaze sidecar` wires your Next.js backend so its outbound `fetch()` calls
transparently route through APIblaze. Each distinct upstream origin (Stripe, an
internal API, anything) lazily becomes a first-class APIblaze proxy on first use
— so you get identity, rate-limits, quotas, and audit wrapped around APIs that
have none of it, with no per-call changes.

```bash
cd my-next-app
npx apiblaze sidecar     # logs you in, mints a scoped key, wires it up
npm install apiblaze
npm run dev              # then open http://localhost:3000/abz-inspector
```

The command mints a **scoped data-plane key** (create/use proxies for one team,
nothing else) into gitignored `.env.local` as `APIBLAZE_TOKEN` + `APIBLAZE_TENANT`.
Your control-plane login stays in `~/.apiblaze` and never enters the project. It
also writes `instrumentation.ts`:

```ts
import { register as apiblaze } from "apiblaze/sidecar";
export function register() { apiblaze(); }
```

The interceptor is stateless and fail-open: if it can't reach APIblaze it falls
back to a direct fetch, so it never breaks your app. External HTTPS origins are
intercepted; same-origin, localhost/private, and known analytics/CDN noise are
left alone.

## How it works

- **No project yet?** If none of your projects point at this machine, `apiblaze dev`
  offers to spin up a throwaway dev proxy (random name like `braveotter42`) pointed at
  `http://localhost:<port>` and tunnels it immediately — pick `none` or `api_key` auth.
- **Server not running yet?** If nothing is listening on the local port, requests aren't
  dropped: each one is printed in full (headers + body, with API keys/JWTs masked and JWTs
  decoded) and answered with a friendly synthetic `200`. The moment your dev server comes
  up, the next request forwards to it automatically. Add `--capture-file <path>` to also
  stream every request/response to a JSON-lines file.

## License

MIT
