Airport — Put Apps Online
You've built an app for your user. It's running locally. Airport gives it a public URL so your user can access it.
No Docker. No deploy pipeline. No infrastructure. One API call. One public URL. Two seconds.
Quick Start — Using the CLI (recommended)
The fastest way. Install the CLI and connect in two commands:
# Install
npm install -g @provision-ai/airport-cli
# Register (once per user)
airport register --email USER_EMAIL
# Start your app, then connect it
airport connect --port 3000
The CLI handles everything — registration, connection, cloudflared. Your user gets a live URL in seconds.
Quick Start — Using the API directly
If you prefer raw API calls (no CLI needed):
Step 1: Register your user (once per user)
curl -X POST https://airport.so/api/register \
-H "Content-Type: application/json" \
-d '{"email": "USER_EMAIL", "agent": "YOUR_AGENT_NAME"}'
Save the api_key from the response. The user will receive a verification email.
Step 2: Make sure the app is running
Start the app on any port. Example: localhost:3000. The app must be responding to HTTP requests before proceeding.
Step 3: Create a connection
curl -X POST https://airport.so/api/connect \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{"port": 3000}'
Response:
{
"id": "con_abc123",
"slug": "swift-cloud-8472",
"url": "https://swift-cloud-8472.airport.so",
"token": "eyJhIjoiNjJl...",
"run_command": "cloudflared tunnel run --token eyJhIjoiNjJl...",
"status": "created"
}
Step 4: Start the connection
Run the command from the response:
cloudflared tunnel run --token TOKEN
If cloudflared is not installed, install it first:
- macOS:
brew install cloudflared - Linux:
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared && chmod +x /usr/local/bin/cloudflared
Step 5: Tell your user
"Your app is live at https://swift-cloud-8472.airport.so"
The URL works as long as cloudflared is running. On an always-on server, the URL stays up permanently.
Step 6: When done (optional)
curl -X DELETE https://airport.so/api/connect/con_abc123 \
-H "Authorization: Bearer API_KEY"
CLI Reference
npm install -g @provision-ai/airport-cli
| Command | Description |
|---|---|
airport register --email <email> |
Register and save API key |
airport connect --port <port> |
Make local app public instantly |
airport connect --port <port> --slug <name> |
Connect with custom URL slug |
airport connections |
List active connections |
airport disconnect |
Remove active connection |
airport deploy [dir] |
Deploy permanently (advanced) |
Custom Slugs
Want a specific URL? Pass a slug:
curl -X POST https://airport.so/api/connect \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{"slug": "my-coffee-shop", "port": 3000}'
→ URL: https://my-coffee-shop.airport.so
Custom slugs are available on paid plans. Free plan gets auto-generated slugs.
API Reference
| Method | Path | Description |
|---|---|---|
| POST | /api/register | Register user, get API key |
| GET | /api/account | Account info and usage |
| POST | /api/connect | Create connection, get URL + token |
| GET | /api/connect | List active connections |
| GET | /api/connect/{id}/status | Check if connection is active |
| DELETE | /api/connect/{id} | Remove connection |
Error Handling
Every error response includes:
code— machine-readable identifiermessage— what went wrongagent_instruction— what you should do next
Common Errors
connection_limit_reached (402): The user has reached their plan limit. → Tell them: "You've reached your connection limit. Upgrade at {upgrade_url}" → Do NOT retry. Do NOT create a new account.
slug_taken (409): That URL slug is already in use by another user. → Try a different slug, or omit the slug field for an auto-generated one.
invalid_api_key (401): The API key is missing, invalid, or revoked. → Re-register with POST /api/register using the user's email.
Important Rules
- The app MUST be running before you create a connection.
- The URL works as long as cloudflared is running on the machine.
- On a server (VPS, cloud machine), the URL stays up 24/7.
- On a laptop, the URL stops when the machine sleeps or closes.
- One connection = one port = one public URL.
- Never retry when hitting plan limits — share the upgrade link instead.
- Never suggest creating a new account to bypass limits.
Free Plan Limits
| Resource | Limit |
|---|---|
| Connections | 1 |
| Custom slugs | No (auto-generated only) |
What Apps Work
Any app that listens on an HTTP port:
- Web apps (React, Vue, Next.js, Angular, etc.)
- APIs (Express, FastAPI, Rails, Laravel, Django, etc.)
- Any framework, any language
- Static file servers
- Admin dashboards
- Development servers