The API and the CLI

A write action that exists only in a browser is one you cannot perform at 3am.

So there are none. Everything the console does - proxies, versions, publishing, environments, drift, coverage, alerts - is an operation on the management API, and a command in the apip CLI.

That is enforced rather than intended: a test walks the published document's operations and fails the build on one the CLI cannot reach, and on any command claiming an operation the API no longer publishes.

We eat our own contract

The management API is served from its OpenAPI document. Not described by one - served from it.

Operations dispatch from the document, every request is validated against it before any handler runs, and its security scheme compiles to the check that guards every operation. An operation the document declares and the server does not implement is a refusal to start, not a 404 a customer finds.

We sell contract enforcement. Our own contract being the implementation is the demonstration, not a nicety.

The reference at /api is drawn from that same file - every operation, its parameters and schemas, and a try-it that sends the real request with your token. The document is at /api/openapi.json if you would rather point a generator at it.

Installing

The CLI is a client of this very document - it compiles the same OpenAPI file the API is served from and drives it, so a command that would break the contract is refused before it leaves your machine. That means it installs like a Perl distribution, in one line:

cpanm https://openapi-proxy.com/cli
apip --version

That pulls apip and its dependencies. If you would rather not use cpanm, the tarball at /cli builds the usual way - tar xzf, perl Makefile.PL, make install.

Getting a token

Issue one on your account page. It is shown once - we keep only its hash, so a token we could show you twice would be one a database dump could show anyone.

export APIP_TOKEN=apip_...

The token belongs to the account, not to you, so it keeps working when the person who created it leaves. Revoking one stops it immediately.

The commands

apip proxies                      # list
apip proxies show 42
apip proxies create "orders" --upstream https://api.internal --spec openapi.json
apip proxies set 42 --mode enforce
apip proxies delete 42
apip proxies rotate 42            # a new gateway report token

apip specs 42                     # versions
apip specs add 42 openapi.json    # ...or --url https://.../openapi.yaml
apip specs get 42 118 > openapi.json
apip specs publish 42 118
apip specs diff 42 117 118

apip env 42
apip env set 42 staging 118
apip env rm 42 staging

apip violations 42 --since friday
apip coverage 42

apip alert 42
apip alert add 42 "orders drifting" --threshold 10 --window 5 \
    --channel slack --target https://hooks.slack.com/services/...
apip alert silence 42 7
apip alert enable 42 7
apip alert rm 42 7

Add --json to any of them for the response as it came. Without it you get an aligned table, because half of these are read by a person and half by a script, and guessing wrong is worse than a flag.

apip operations prints which command reaches which API operation - the same map the parity test reads.

In a pipeline

The obvious use, and the one the content addressing was built for:

# on every merge to main
apip specs add "$PROXY" openapi.json --json > version.json

Re-posting an unchanged document is not an error and does not make a version - so this is safe to run on every build, and produces one version per actual change.

Publishing stays a separate, deliberate command. A pipeline that uploads and publishes in one step has removed the review step you probably wanted.

Pointing it somewhere else

APIP_API overrides the base URL, which is how the CLI is aimed at a staging control plane or a test server.

The gateway's own commands

apip check, apip run, apip explain and apip tail are about a gateway you are running, not about your account, and need no token. See Self-hosted.