# What is ngrok?
Source: https://ngrok.com/docs/about/index
ngrok is developer infrastructure that routes and secures traffic to your apps, APIs, and AI models, wherever they run.
ngrok is developer infrastructure that routes and secures traffic to your apps, APIs, and AI models.
It manages connectivity between all of the tools and platforms you use to put your services online, no matter where they're deployed or what network they're on.
ngrok's core products are Gateway, AI Gateway, and Share Localhost.
Gateway owns the connectivity primitives, and the other products integrate them.
## Products
An all-in-one cloud networking platform that secures, transforms, and routes traffic to your services.
Unlike cloud provider gateways locked to their own networks, ngrok works the same in AWS, Azure, GCP, on-prem, and your customer's networks.
Route, secure, and manage traffic to any LLM—cloud or local—through one endpoint.
Use OpenAI, Anthropic, and more without signing up for each provider.
Expose a service running on `localhost` to the internet, even from behind a NAT or firewall.
Skip port forwarding, DNS changes, and firewall rules entirely.
## Why ngrok?
ngrok works everywhere, and it works *the same* everywhere: AWS, GCP, Azure, your on-prem data center, a Raspberry Pi, or your laptop.
Collapse the reverse proxy, load balancer, API gateway, WAF, and DDoS protection into one platform with unified configuration and observability.
Authentication, attack protection, and traffic acceleration are handled for you, so you can focus on your app instead of networking configuration.
Stop wrestling with CIDRs, ports, and TLS certificates.
Work with application primitives like authentication and request routing instead.
Run ngrok in local development exactly the way you run it in production, eliminating the bugs that come from environment drift.
Public, predictable pricing that anyone can start with using a credit card.
You pay only for what you use.
## What can you do with ngrok?
### Build and test
* **[Share a local app](/docs/share-localhost/overview)**: Put anything on localhost behind a stable, secure public URL.
* **[Test webhooks locally](/docs/share-localhost/webhooks)**: Inspect, replay, and verify requests while you build.
* **[Connect local MCP servers](/docs/gateway/api-gateway/mcp-gateway)**: Let ChatGPT and Claude reach tools on your machine.
### Play
* **[Host a Minecraft server](/docs/gateway/examples/minecraft)**: Let your friends join, and block the griefers, without port forwarding.
### Deploy and run
* **[Route traffic to self-hosted models](/docs/ai-gateway/guides/use-a-model-you-run-yourself)**: Privately connect to any hardware, in any network, over an AI gateway.
* **[Run preview and CI workloads](/docs/gateway/examples/ephemeral-workloads)**: Give every ephemeral service a secure public URL.
### Deliver and connect
* **[Deliver and secure APIs](/docs/gateway/api-gateway/get-started)**: Route, authenticate, and protect requests through an API gateway.
* **[Reach customer networks](/docs/gateway/site-to-site-connectivity/overview)**: Connect to customer APIs and databases with site-to-site connectivity.
* **[Receive webhooks on-prem](/docs/gateway/webhooks-to-on-prem/overview)**: Verify signatures for 70+ providers at one webhook gateway.
* **[Connect privately across networks](/docs/gateway/endpoints/internal-endpoints)**: Reach across network boundaries without public URLs, open ports, or VPNs.
* **[Connect device fleets](/docs/gateway/device-gateway/overview)**: Reach devices in the field through a device gateway, no inbound ports.
* **[Open SSH and RDP sessions](/docs/gateway/ssh-rdp)**: Reach a shell or desktop on a remote machine without a VPN.
## Gateway primitives
Gateway owns the primitives that move traffic.
AI Gateway and Share Localhost build on them, so what you learn once applies wherever you use ngrok.
* [Endpoints](/docs/gateway/endpoints/): The URLs traffic arrives on, whether created by an agent or in the cloud.
* [Traffic Policy](/docs/gateway/traffic-policy/): Filter, match, manage, and orchestrate traffic to your endpoints.
* [Domains & TLS](/docs/gateway/domains/): Serve traffic on your own hostnames, and manage the certificates that terminate TLS.
* [Traffic observability](/docs/obs/): Capture and replay requests and responses.
* [Identity and access](/docs/iam/): Manage credentials for human users and automated processes.
## How ngrok works
Each product has its own architecture and request flow.
How ngrok's global cloud service and agent software deliver traffic to your upstream services.
How ngrok.ai routes requests, validates access keys, and handles failover across model providers.
How the ngrok agent creates encrypted tunnels that deliver internet traffic to your local machine.
## What's next?
* Start with the product that fits your use case: [Gateway](/docs/gateway/overview), [AI Gateway](/docs/ai-gateway/overview), or [Share Localhost](/docs/share-localhost/overview).
* Browse the [Gateway examples collection](/docs/gateway/examples/) to see common patterns implemented end to end.
* Check the [FAQ](/docs/faq) for common questions, or the [glossary](/docs/glossary) for ngrok terminology.
# Agent SDKs
Source: https://ngrok.com/docs/agent-sdks/index
Learn about ngrok Agent SDKs for embedding ngrok directly into your applications using Go, JavaScript, Python, and Rust libraries.
Agent SDKs enable you to embed ngrok directly into your application. They allow
you to programmatically create ngrok endpoints. You handle connections from
ngrok's cloud service just as if you opened a socket to listen on a port.
## Example usage
1. Install the SDK:
```sh theme={null}
go get golang.ngrok.com/ngrok/v2
```
2. Add the following to your app:
```go theme={null}
import "golang.ngrok.com/ngrok/v2"
func connectNgrok() {
fwd, err := ngrok.Forward(context.Background(),
ngrok.WithUpstream("http://localhost:8085"),
)
if err != nil {
log.Fatal(err)
}
log.Println("Available at:", fwd.URL())
select {}
}
```
3. Set your authtoken and restart your app:
```sh theme={null}
export NGROK_AUTHTOKEN=
```
1. Install the SDK:
```sh theme={null}
npm install @ngrok/ngrok
```
2. Add the following to your app:
```js theme={null}
const ngrok = require("@ngrok/ngrok");
async function forwardToApp() {
const forwarder = await ngrok.forward({
addr: "localhost:8085",
authtoken_from_env: true,
});
console.log(`Available at: ${forwarder.url()}`);
}
```
3. Set your authtoken and restart your app:
```sh theme={null}
export NGROK_AUTHTOKEN=
```
1. Install the SDK:
```sh theme={null}
pip install ngrok
```
2. Add the following to your app:
```python theme={null}
import ngrok
def connect_ngrok():
forwarder = ngrok.forward("localhost:8085", authtoken_from_env=True)
print(f"Available at: {forwarder.url()}")
```
3. Set your authtoken and restart your app:
```sh theme={null}
export NGROK_AUTHTOKEN=
```
1. Install the SDK:
```sh theme={null}
cargo add ngrok
```
2. Add the following to your app:
```rust theme={null}
use ngrok::config::ForwarderBuilder;
use ngrok::prelude::*;
use url::Url;
async fn connect_ngrok() -> Result<(), Box> {
let sess = ngrok::Session::builder()
.authtoken_from_env()
.connect()
.await?;
let mut listener = sess
.http_endpoint()
.listen_and_forward(Url::parse("http://localhost:8085")?)
.await?;
println!("Available at: {:?}", listener.url());
let _ = listener.join().await;
Ok(())
}
```
3. Set your authtoken and restart your app:
```sh theme={null}
export NGROK_AUTHTOKEN=
```
## Supported languages
| Language | Docs | Quickstart | Repository | Status |
| - | - | - | - | - |
| Go | [ngrok-go docs](https://pkg.go.dev/golang.ngrok.com/ngrok/v2) | [ngrok-go quickstart](/docs/getting-started/go/) | [github.com/ngrok/ngrok-go](https://github.com/ngrok/ngrok-go) | Stable |
| Rust | [ngrok-rust docs](https://docs.rs/ngrok/latest/ngrok/) | [ngrok-rust quickstart](/docs/getting-started/rust/) | [github.com/ngrok/ngrok-rust](https://github.com/ngrok/ngrok-rust) | Stable |
| Python | [ngrok-python docs](https://ngrok.github.io/ngrok-python/) | [ngrok-python quickstart](/docs/getting-started/python/) | [github.com/ngrok/ngrok-python](https://github.com/ngrok/ngrok-python) | Stable |
| JavaScript | [ngrok-javascript docs](https://ngrok.github.io/ngrok-javascript/) | [ngrok-javascript quickstart](/docs/getting-started/javascript/) | [github.com/ngrok/ngrok-javascript](https://github.com/ngrok/ngrok-javascript) | Stable |
| Java | | | [github.com/ngrok/ngrok-java](https://github.com/ngrok/ngrok-java) | Alpha |
## When to use Agent SDKs
Agent SDKs are often a better fit for your use case over using the [ngrok
agent](/docs/gateway/agent/). This is especially true when running ngrok with
production apps. Agent SDKs are a better choice if:
* You don't want to manage the lifetime of a separate agent process
* You don't want to bundle and distribute the ngrok agent
* The ngrok agent doesn't run on your target platform
* The ngrok agent's resource requirements are too high for your target platform
* You want fine-grained programmatic control over the agent's functionality
## Agent SDKs pricing
The agent SDKs are available to all ngrok users at no additional charge. You
only incur costs if the resources provisioned by the SDKs incur a cost. For more information, see the [ngrok Pricing page](https://ngrok.com/pricing).
# Claude Code
Source: https://ngrok.com/docs/ai-gateway/agents/claude-code
Route Claude Code through the ngrok AI Gateway with two environment variables to track usage, fail over, and bill to one access key.
[Claude Code](https://code.claude.com/docs) is Anthropic's agentic coding tool for the terminal, IDEs, and desktop.
It speaks the Anthropic Messages API, so pointing its base URL at the AI Gateway sends every model request through ngrok.ai, where it shows up in [observability](/docs/ai-gateway/observability) and follows your [access key configuration](/docs/ai-gateway/guides/access-key-configurations).
## What you'll need
* [Claude Code](https://code.claude.com/docs/en/setup) installed.
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai).
## Point the CLI at the gateway
Set two environment variables in your shell:
```bash theme={null}
export ANTHROPIC_BASE_URL="https://gateway.ngrok.ai"
export ANTHROPIC_AUTH_TOKEN="ng-xxxxx-g1-xxxxx"
```
* `ANTHROPIC_BASE_URL` is the gateway URL without `/v1`, since Claude Code appends `/v1/messages` itself
* `ANTHROPIC_AUTH_TOKEN` is your access key, which Claude Code sends as an `Authorization: Bearer` header
`ANTHROPIC_AUTH_TOKEN` takes precedence over a saved claude.ai login, so Claude Code uses your access key as soon as you start it.
If `ANTHROPIC_API_KEY` is also set in your environment, unset it to avoid an auth conflict warning.
To keep the configuration across terminals and for background agents, move the same values into the `env` block of `~/.claude/settings.json`:
```json theme={null}
{
"env": {
"ANTHROPIC_BASE_URL": "https://gateway.ngrok.ai",
"ANTHROPIC_AUTH_TOKEN": "ng-xxxxx-g1-xxxxx"
}
}
```
Don't put your access key in a project's `.claude/settings.json`.
That file is committed and shared with everyone who clones the repository.
## Test the connection
Before you start Claude Code, send a short request straight to the gateway from the same shell:
```bash theme={null}
curl https://gateway.ngrok.ai/v1/messages \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model": "claude-sonnet-5-5", "max_tokens": 16, "messages": [{"role": "user", "content": "Say hello."}]}'
```
A JSON response that starts with `{"id":"msg_` means the URL and access key work.
A `401` means the gateway rejected the access key.
Then start `claude`, run `/status`, and check two lines:
* `Anthropic base URL` shows `https://gateway.ngrok.ai`
* `Auth token` names `ANTHROPIC_AUTH_TOKEN`
Send any prompt, then confirm the request in AI Gateway [observability](/docs/ai-gateway/observability) in [app.ngrok.ai](https://app.ngrok.ai).
## Choose a model
Claude Code's built-in model aliases, such as `opus`, `sonnet`, and `haiku`, resolve to Anthropic model IDs like `claude-sonnet-5-5`.
The gateway finds those IDs in the [model catalog](/docs/ai-gateway/reference/model-catalog), so `/model` and `--model` work without extra setup.
To pin the model behind each alias, set these variables alongside the base URL:
```bash theme={null}
export ANTHROPIC_DEFAULT_OPUS_MODEL="claude-opus-5-5"
export ANTHROPIC_DEFAULT_SONNET_MODEL="claude-sonnet-5-5"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="claude-haiku-5-5"
```
Use the catalog's model IDs rather than dated snapshot IDs like `claude-haiku-4-5-20251001`, which the gateway doesn't match.
To add the gateway's Claude models to the `/model` picker, turn on Claude Code's gateway model discovery:
```bash theme={null}
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
```
At startup, Claude Code reads the gateway's model list, which only includes models your access key is allowed to call, and adds the Claude models in it, such as `anthropic/claude-sonnet-5-5`.
The gateway doesn't serve Anthropic's token counting endpoint, so `/context` shows estimated token counts.
Claude Code only works with Claude models through the gateway.
`/v1/messages` only reaches providers that support the Anthropic Messages API, and Anthropic doesn't support routing Claude Code to other models.
## Use other surfaces
The CLI reads the shell variables and `~/.claude/settings.json`.
Other surfaces need the same two values in a different place:
* VS Code extension: set them in `claudeCode.environmentVariables` in your VS Code user settings
* Claude Agent SDK: pass them in the SDK's `env` option, which sets the environment of the Claude Code process it spawns
* Claude desktop app: turn on Developer Mode, then enter the gateway details under **Developer** > **Configure Third-Party Inference**
See Claude Code's guide to [connecting to an LLM gateway](https://code.claude.com/docs/en/llm-gateway-connect#configure-each-surface) for each surface.
## Troubleshooting
| Symptom | Fix |
| - | - |
| `401` errors | Check that `ANTHROPIC_AUTH_TOKEN` holds a current access key from [app.ngrok.ai](https://app.ngrok.ai/keys) |
| Claude Code asks you to log in | Set the variables in your shell or in `~/.claude/settings.json`, not in a project settings file, which Claude Code reads only after its first-run setup |
| `/status` doesn't show the gateway URL | Start `claude` from the shell where you exported the variables, or move them to `~/.claude/settings.json` |
| A request fails with a model error | Check that the model ID matches the [model catalog](/docs/ai-gateway/reference/model-catalog) exactly, without a date suffix, and that your [access key configuration](/docs/ai-gateway/guides/access-key-configurations) allows it |
| Long responses stop partway through | Set `totalTimeout` to `15m` in [account settings](/docs/ai-gateway/guides/account-settings#streaming-responses). A saved total timeout caps the whole stream, and saving any account setting stores the `2m` default |
For gateway-side errors, see [Debug failed requests](/docs/ai-gateway/guides/debugging).
## Next steps
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Scope what an access key can call
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model when the first one fails
* [Observability](/docs/ai-gateway/observability): See which model served each request
# Codex
Source: https://ngrok.com/docs/ai-gateway/agents/codex
Add the ngrok AI Gateway as a custom model provider in the OpenAI Codex CLI to track usage and route requests with one access key.
[Codex](https://github.com/openai/codex) is OpenAI's coding agent for the terminal.
It reaches the AI Gateway as a custom model provider over the OpenAI Responses API, so its requests show up in [observability](/docs/ai-gateway/observability) and follow your [access key configuration](/docs/ai-gateway/guides/access-key-configurations).
## What you'll need
* The [Codex CLI](https://github.com/openai/codex#quickstart) installed.
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai).
## Add the gateway as a model provider
Export your access key in your shell profile, such as `~/.zshrc` or `~/.bashrc`, so Codex can read it:
```bash theme={null}
export NGROK_AI_GATEWAY_KEY="ng-xxxxx-g1-xxxxx"
```
Save Codex's built-in model catalog to a file:
```bash theme={null}
codex debug models > ~/.codex/ngrok-models.json
```
Codex looks up each model's context window, reasoning levels, and tools in a catalog.
The gateway's model list doesn't include those details, so without the file Codex warns that model metadata isn't found and falls back to generic defaults.
Run the command again after you update Codex to pick up new models.
Add the gateway as a provider in `~/.codex/config.toml`:
```toml theme={null}
model = "gpt-5.5"
model_provider = "ngrok"
model_catalog_json = "~/.codex/ngrok-models.json"
[model_providers.ngrok]
name = "ngrok AI Gateway"
base_url = "https://gateway.ngrok.ai/v1"
env_key = "NGROK_AI_GATEWAY_KEY"
wire_api = "responses"
```
This configuration:
* Defines a provider named `ngrok` that points at the gateway
* Reads your access key from `NGROK_AI_GATEWAY_KEY` and sends it as an `Authorization: Bearer` header
* Uses the Responses API, the only wire protocol current Codex versions support
* Makes `ngrok` the default provider, with `gpt-5.5` as the default model
* Loads model details from the catalog you saved
Keep the provider in your user-level `~/.codex/config.toml`.
Codex ignores `model_provider` and `model_providers` in a project's `.codex/config.toml`.
The provider ID can't be `openai`, `ollama`, or `lmstudio`, which Codex reserves for its built-in providers.
## Test the connection
Send a single prompt from the command line:
```bash theme={null}
codex exec "Explain what a hash map is in two sentences."
```
The header Codex prints before the response should list `provider: ngrok` and your model.
Confirm the request in AI Gateway [observability](/docs/ai-gateway/observability) in [app.ngrok.ai](https://app.ngrok.ai).
## Choose a model
Codex only supports the `/v1/responses` API.
Check the [model catalog](/docs/ai-gateway/reference/model-catalog) before you point Codex at a non-OpenAI model.
Pass `--model` (or `-m`) to start a session on a different model:
```bash theme={null}
codex --model gpt-5.4
```
Pick a model that's in both your saved catalog and the [ngrok.ai model catalog](/docs/ai-gateway/reference/model-catalog), and use its plain ID.
A `provider:model` name such as `openai:gpt-5.5` reaches the gateway, but Codex doesn't find it in the catalog and falls back to generic defaults.
## Keep OpenAI as your default
To keep Codex on your OpenAI login by default and use the gateway only when you ask for it, put the gateway settings in a profile instead of `config.toml`.
Create `~/.codex/ngrok.config.toml`:
```toml theme={null}
model_provider = "ngrok"
model = "gpt-5.5"
model_catalog_json = "~/.codex/ngrok-models.json"
[model_providers.ngrok]
name = "ngrok AI Gateway"
base_url = "https://gateway.ngrok.ai/v1"
env_key = "NGROK_AI_GATEWAY_KEY"
wire_api = "responses"
```
Start a gateway session with the profile:
```bash theme={null}
codex --profile ngrok
```
Codex loads `config.toml` first, then layers the profile on top, so sessions without `--profile ngrok` stay on OpenAI.
## Troubleshooting
| Symptom | Fix |
| - | - |
| `Reconnecting...` messages, then `401 Unauthorized` | Check that `NGROK_AI_GATEWAY_KEY` is exported in the shell that starts Codex, and that it holds a current access key |
| Requests still go to OpenAI | Move `model_provider` and `[model_providers.ngrok]` to `~/.codex/config.toml` or a profile, since a project config can't set them |
| `Model metadata for not found` at startup | Save the model catalog and set `model_catalog_json`, then use a plain model ID that's in it |
| Long responses stop partway through | Set `totalTimeout` to `15m` in [account settings](/docs/ai-gateway/guides/account-settings#streaming-responses). A saved total timeout caps the whole stream, and saving any account setting stores the `2m` default |
For gateway-side errors, see [Debug failed requests](/docs/ai-gateway/guides/debugging).
## Next steps
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Scope what an access key can call
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model when the first one fails
* [Observability](/docs/ai-gateway/observability): See which model served each request
# Cursor
Source: https://ngrok.com/docs/ai-gateway/agents/cursor
Point Cursor's OpenAI base URL override at the ngrok AI Gateway to chat with catalog or self-hosted models, and learn what it doesn't cover.
[Cursor](https://cursor.com) is a code editor with a built-in agent.
It reaches custom models by overriding the base URL of its OpenAI provider, so the AI Gateway stands in for OpenAI.
This needs a paid Cursor plan.
Free plans can only use Cursor's **Auto** model and can't select a named model, which is what a model you add yourself is.
## What you'll need
* [Cursor](https://cursor.com/download) installed, on a paid plan.
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai).
## Point Cursor at the gateway
Open **Cursor Settings**, go to **Models**, and expand **API Keys**:
1. Turn on **OpenAI API Key** and paste your ngrok.ai access key.
The field is labeled OpenAI, but Cursor sends the key to whatever endpoint you configure below.
2. Turn on **Override OpenAI Base URL** and enter `https://gateway.ngrok.ai/v1`.
Keep the `/v1` suffix: Cursor appends `/chat/completions` to whatever you enter.
3. Select **+ Add model**, enter a model ID from the [model catalog](/docs/ai-gateway/reference/model-catalog), such as `gpt-5.5`, and enable it.
Use `provider:model` to pin a provider.
4. Select **Verify** to confirm the gateway answers.
The base URL override is global.
While it's on, Cursor routes its other OpenAI-model traffic to the gateway too, which fails for models your access key can't reach.
Turn the override off to go back to Cursor's own models.
## Test the connection
Pick your model in the chat model selector and send a prompt:
Explain what a hash map is in two sentences.
Confirm the request in AI Gateway [observability](/docs/ai-gateway/observability) in [app.ngrok.ai](https://app.ngrok.ai).
## What the override doesn't cover
Expect chat, not the whole editor.
Three Cursor behaviors limit how far a custom model reaches:
* Tab completion always uses Cursor's built-in models. It never reaches your endpoint.
* Agent and Edit also rely on Cursor's own models, so Cursor may refuse them while a custom API key is set and ask you to disable the key.
* Where agent runs do work, Cursor's tool definitions over an overridden base URL aren't strictly OpenAI-shaped, so tool calls can fail against a self-hosted model even when plain chat succeeds.
## Use a model you run yourself
To reach a model on your own machine, register it as a [custom provider](/docs/ai-gateway/concepts/custom-providers), then add its `provider:model` name as a model, such as `ollama:llama3.2`.
See [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself) for the full setup.
## Next steps
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Scope what an access key can call
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model when the first one fails
* [Observability](/docs/ai-gateway/observability): See which model served each request
# Hermes
Source: https://ngrok.com/docs/ai-gateway/agents/hermes
Install the ngrok AI Gateway plugin for Hermes Agent to use your gateway's models as a Hermes model provider with one access key.
[Hermes Agent](https://hermes-agent.nousresearch.com) is Nous Research's open-source AI agent for the terminal.
The [ngrok AI Gateway plugin](https://github.com/ngrok/hermes-ngrok) adds the gateway as a Hermes model provider, so Hermes can use every model your access key reaches.
## What you'll need
* [Hermes Agent](https://hermes-agent.nousresearch.com) 0.21.6 or later installed.
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai/keys).
## Install the plugin
Install the plugin with the Hermes CLI:
```bash theme={null}
hermes plugins install ngrok-ai-gateway
```
Enter your access key when prompted.
Hermes saves it as `NGROK_AI_GATEWAY_KEY`.
Plugins are installed per Hermes profile, so install it again in any other profile that needs it.
## Choose a model
Run `hermes model` and select **ngrok AI Gateway**, or pass `--provider ngrok` when you start Hermes.
The model list comes from your gateway, so it shows the models your access key is allowed to call, by full catalog ID such as `openai/gpt-5.5`.
Model IDs follow the gateway's [model naming](/docs/ai-gateway/concepts/models): a model ID such as `gpt-5.5`, or `provider:model` to pin a provider, such as `openai:gpt-5.5`.
## Test the connection
Send a single prompt from the command line:
```bash theme={null}
hermes chat --provider ngrok --model gpt-5.5 -q "Explain what a hash map is in two sentences."
```
Confirm the request in AI Gateway [observability](/docs/ai-gateway/observability) in [app.ngrok.ai](https://app.ngrok.ai).
## Use a cheaper model for background tasks
Background tasks like context compression and title generation use your main model.
To send them to a cheaper model through the gateway, set the provider and model for each task in `~/.hermes/config.yaml`:
```yaml theme={null}
auxiliary:
compression:
provider: ngrok
model: gpt-5.4-mini
title_generation:
provider: ngrok
model: gpt-5.4-mini
```
## What the plugin sends
The plugin sends chat and model list requests to `https://gateway.ngrok.ai/v1` with your access key.
Each request carries a `User-Agent: hermes-agent/ (ngrok-plugin)` header.
The plugin makes no other network requests, doesn't read files, and doesn't run background processes.
## Next steps
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Scope what an access key can call
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model when the first one fails
* [Observability](/docs/ai-gateway/observability): See which model served each request
# Agents
Source: https://ngrok.com/docs/ai-gateway/agents/index
Route Claude Code, Codex, Cursor, Hermes, and other coding agents through the ngrok AI Gateway to share model access and track usage.
**Prerequisite**: Complete the [Quickstart](/docs/ai-gateway/quickstart) to create an access key on [app.ngrok.ai](https://app.ngrok.ai).
Coding agents that let you change their base URL can send their model requests through the AI Gateway.
Each agent then authenticates with an ngrok.ai [access key](/docs/ai-gateway/concepts/access-keys) instead of a separate provider account, and every request shows up in one place.
Routing agents through the gateway gives you:
* One access key for every provider in the [model catalog](/docs/ai-gateway/reference/model-catalog), billed to your credits or your own provider keys
* Per-request [observability](/docs/ai-gateway/observability), with usage you can group by access key
* [Fallback models](/docs/ai-gateway/guides/configure-fallback-models) and automatic retries when a provider fails
* Limits on which providers and models each key can call
* A path to [models you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself), such as Ollama or vLLM
## Supported agents
Anthropic's agentic coding tool, configured with two environment variables
OpenAI's terminal coding agent, configured as a custom model provider
AI code editor, configured with an OpenAI base URL override
Nous Research's terminal agent, configured with the ngrok plugin
Open-source terminal agent, configured as a custom provider
Terminal coding agent, configured in its models file
Code editor with an agent panel, configured as an OpenAI-compatible provider
Any agent that accepts a custom OpenAI or Anthropic base URL
## How each agent connects
Each agent speaks one API format, which decides the base URL it needs:
| Agent | API format | Base URL |
| - | - | - |
| Claude Code | Anthropic Messages | `https://gateway.ngrok.ai` |
| Codex | OpenAI Responses | `https://gateway.ngrok.ai/v1` |
| Cursor | OpenAI Chat Completions | `https://gateway.ngrok.ai/v1` |
| Hermes | OpenAI Chat Completions | `https://gateway.ngrok.ai/v1`, set by the plugin |
| OpenCode | OpenAI Chat Completions | `https://gateway.ngrok.ai/v1` |
| Pi | OpenAI Chat Completions | `https://gateway.ngrok.ai/v1` |
| Zed | OpenAI Chat Completions | `https://gateway.ngrok.ai/v1` |
The format also decides which models an agent can reach.
Chat Completions reaches the most providers.
The Messages and Responses formats only reach providers that support them, so Claude Code works with Claude models and Codex works best with OpenAI models.
## Set up for agent traffic
Coding agents send long, streaming requests, often many per task.
A few settings keep that traffic manageable:
* Create a separate access key for each agent or teammate, so you can [group usage by access key](/docs/ai-gateway/observability) and revoke one without touching the others.
* Set `totalTimeout` to `15m` in [account settings](/docs/ai-gateway/guides/account-settings#streaming-responses). A saved total timeout caps the whole stream, and saving any account setting stores the `2m` default, which can cut off a long agent response.
* Scope each key to the models it needs with an [access key configuration](/docs/ai-gateway/guides/restrict-providers-and-models).
## Next steps
* [Claude Code](/docs/ai-gateway/agents/claude-code): Route Claude Code through the gateway
* [Codex](/docs/ai-gateway/agents/codex): Add the gateway as a Codex model provider
* [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself): Reach a model on your own machine, such as Ollama or vLLM
# OpenCode
Source: https://ngrok.com/docs/ai-gateway/agents/opencode
Connect OpenCode to the ngrok AI Gateway to reach any model in the catalog, or a model you run yourself, with one access key.
[OpenCode](https://opencode.ai) is an open-source terminal coding agent.
It reaches the AI Gateway as a custom OpenAI-compatible provider, so one access key covers every model you add to its config.
## What you'll need
* [OpenCode](https://opencode.ai/docs/#install) installed.
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai).
## Add the gateway as a provider
Export your access key so OpenCode can read it:
```bash theme={null}
export NGROK_AI_GATEWAY_KEY="ng-xxxxx-g1-xxxxx"
```
Add the gateway as a provider in `~/.config/opencode/opencode.json`, or in an `opencode.json` beside your project:
```json theme={null}
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"ngrok": {
"npm": "@ai-sdk/openai-compatible",
"name": "ngrok AI Gateway",
"options": {
"baseURL": "https://gateway.ngrok.ai/v1",
"apiKey": "{env:NGROK_AI_GATEWAY_KEY}"
},
"models": {
"gpt-5.5": {
"name": "GPT-5.5 (via ngrok)",
"limit": { "context": 1050000, "output": 128000 }
},
"claude-sonnet-5-5": {
"name": "Claude Sonnet 5.5 (via ngrok)",
"limit": { "context": 1000000, "output": 128000 }
}
}
}
}
}
```
Each key in `models` is the model name OpenCode sends to the gateway.
Use any model ID from the [model catalog](/docs/ai-gateway/reference/model-catalog), or `provider:model` to pin a provider.
The `limit` values are optional, but they let OpenCode track how much context is left.
## Test the connection
Start OpenCode, run `/models`, and pick one of the models under **ngrok AI Gateway**.
Or send a single prompt from the command line:
```bash theme={null}
opencode run -m "ngrok/gpt-5.5" "Explain what a hash map is in two sentences."
```
The `-m` value is your provider ID, a slash, then the model key from `opencode.json`.
Confirm the request in AI Gateway [observability](/docs/ai-gateway/observability) in [app.ngrok.ai](https://app.ngrok.ai).
## Use a model you run yourself
To reach a model on your own machine, register it as a [custom provider](/docs/ai-gateway/concepts/custom-providers), then add its `provider:model` name to `models`, such as `ollama:llama3.2`.
See [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself) for the full setup.
## Next steps
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Scope what an access key can call
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model when the first one fails
* [Observability](/docs/ai-gateway/observability): See which model served each request
# Other agents
Source: https://ngrok.com/docs/ai-gateway/agents/other
Connect any coding agent that accepts a custom OpenAI or Anthropic base URL to the ngrok AI Gateway with three values.
Coding agents that let you replace their built-in provider with a custom endpoint can usually reach the AI Gateway, even without a dedicated guide.
Want instructions for a specific coding agent?
Log in to [app.ngrok.ai](https://app.ngrok.ai), click **Give feedback**, and let the team know which one.
## What you'll need
* A coding agent that accepts a custom base URL and API key.
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai).
## Connect your agent
Every agent needs the same three values:
| Value | What to enter |
| - | - |
| Base URL | `https://gateway.ngrok.ai/v1` for OpenAI-format agents, `https://gateway.ngrok.ai` for Anthropic-format agents |
| API key | Your [access key](https://app.ngrok.ai/keys), such as `ng-xxxxx-g1-xxxxx` |
| Model | A model ID from the [model catalog](/docs/ai-gateway/reference/model-catalog), or `provider:model` to pin a provider |
Anthropic-format agents append `/v1/messages` to the base URL themselves, so leave `/v1` off for those.
Agents that fill their model picker from `GET /v1/models` see the models your access key is allowed to call, listed by full catalog ID such as `openai/gpt-5.5`.
Those IDs work as the model value, too.
## Pick an API format
The gateway serves these endpoints, so an agent can use whichever format it speaks:
| Endpoint | Format |
| - | - |
| `/v1/chat/completions` | OpenAI Chat Completions |
| `/v1/responses` | OpenAI Responses |
| `/v1/messages` | Anthropic Messages |
`/v1/messages` only reaches providers that support the Anthropic Messages surface.
For a model you run yourself with Ollama, LM Studio, or vLLM, point the agent at `/v1/chat/completions` or `/v1/responses`.
Access keys work in both the `Authorization: Bearer` and `x-api-key` headers, so you don't need to match the header your agent sends.
## Test the connection
Send a prompt from the agent, then confirm the request in AI Gateway [observability](/docs/ai-gateway/observability) in [app.ngrok.ai](https://app.ngrok.ai).
If the agent reports an error, check [Debugging](/docs/ai-gateway/guides/debugging) and the [error codes reference](/docs/ai-gateway/reference/error-codes).
## Next steps
* [Use with other SDKs](/docs/ai-gateway/sdks/other): Raw HTTP examples for each API format
* [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself): Reach a model on your own machine, such as Ollama or vLLM
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Scope what an access key can call
# Pi
Source: https://ngrok.com/docs/ai-gateway/agents/pi
Connect the Pi terminal coding agent to the ngrok AI Gateway to reach any model in the catalog, or a model you run yourself.
[Pi](https://pi.dev) is a terminal coding agent.
It reaches the AI Gateway as a custom provider in its models file, so one access key covers every model you list there.
## What you'll need
* [Pi](https://pi.dev) installed.
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai).
## Add the gateway as a provider
Export your access key so Pi can read it:
```bash theme={null}
export NGROK_AI_GATEWAY_KEY="ng-xxxxx-g1-xxxxx"
```
Add the gateway as a provider in `~/.pi/agent/models.json`:
```json theme={null}
{
"providers": {
"ngrok": {
"baseUrl": "https://gateway.ngrok.ai/v1",
"apiKey": "$NGROK_AI_GATEWAY_KEY",
"api": "openai-completions",
"models": [
{ "id": "gpt-5.5" },
{ "id": "claude-sonnet-5-5" }
]
}
}
}
```
`id` is the model name Pi sends to the gateway: a model ID from the [model catalog](/docs/ai-gateway/reference/model-catalog), or `provider:model` to pin a provider.
It's the only field a model entry needs, though you can add `name`, `contextWindow`, and `maxTokens` to label it and track context accurately.
## Test the connection
Send a single prompt from the command line:
```bash theme={null}
pi --provider ngrok --model "gpt-5.5" -p "Explain what a hash map is in two sentences."
```
In an interactive session, run `/model` and pick one of the **ngrok** models instead.
Confirm the request in AI Gateway [observability](/docs/ai-gateway/observability) in [app.ngrok.ai](https://app.ngrok.ai).
## Use a model you run yourself
To reach a model on your own machine, register it as a [custom provider](/docs/ai-gateway/concepts/custom-providers), then add its `provider:model` name to `models`, such as `ollama:llama3.2`.
See [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself) for the full setup.
## Next steps
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Scope what an access key can call
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model when the first one fails
* [Observability](/docs/ai-gateway/observability): See which model served each request
# Zed
Source: https://ngrok.com/docs/ai-gateway/agents/zed
Connect the Zed editor's agent panel to the ngrok AI Gateway as an OpenAI-compatible provider to use catalog or self-hosted models.
[Zed](https://zed.dev) is a code editor with a built-in agent panel.
It reaches the AI Gateway as an OpenAI-compatible LLM provider, so the agent panel can use any model you list in your settings.
## What you'll need
* [Zed](https://zed.dev/download) installed.
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai).
## Add the gateway as a provider
Add the provider to your Zed `settings.json`:
```json theme={null}
{
"language_models": {
"openai_compatible": {
"ngrok": {
"api_url": "https://gateway.ngrok.ai/v1",
"available_models": [
{
"name": "gpt-5.5",
"display_name": "GPT-5.5 (via ngrok)",
"max_tokens": 1050000
},
{
"name": "claude-sonnet-5-5",
"display_name": "Claude Sonnet 5.5 (via ngrok)",
"max_tokens": 1000000
}
]
}
}
}
}
```
For each model:
* `name` is the model name Zed sends to the gateway: a model ID from the [model catalog](/docs/ai-gateway/reference/model-catalog), or `provider:model` to pin a provider
* `max_tokens` is the model's context window
* `capabilities` is optional; set `"images": true` inside it for models that accept images
Next, add your access key through the Zed UI.
Open the command palette, run **agent: open settings**, select **LLM Providers**, then **Configure**, find **ngrok** in the provider list, paste your access key, and press **Enter**.
## Test the connection
Create a new agent thread, pick one of your models from the selector at the bottom of the agent panel's message editor, and send a prompt:
Explain what a hash map is in two sentences.
Confirm the request in AI Gateway [observability](/docs/ai-gateway/observability) in [app.ngrok.ai](https://app.ngrok.ai).
## Use a model you run yourself
To reach a model on your own machine, register it as a [custom provider](/docs/ai-gateway/concepts/custom-providers), then add its `provider:model` name to `available_models`, such as `ollama:llama3.2`.
See [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself) for the full setup.
## Next steps
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Scope what an access key can call
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model when the first one fails
* [Observability](/docs/ai-gateway/observability): See which model served each request
# Create an AI Gateway access key configuration
Source: https://ngrok.com/docs/ai-gateway/api-reference/access-key-configurations/create
openapi/ai-gateway.yaml POST /access-key-configurations
Create a reusable access key configuration with provider/model scope and routing rules.
# Delete an AI Gateway access key configuration
Source: https://ngrok.com/docs/ai-gateway/api-reference/access-key-configurations/delete
openapi/ai-gateway.yaml DELETE /access-key-configurations/{id}
Delete an AI Gateway access key configuration by ID.
# Get an AI Gateway access key configuration
Source: https://ngrok.com/docs/ai-gateway/api-reference/access-key-configurations/get
openapi/ai-gateway.yaml GET /access-key-configurations/{id}
Get a single AI Gateway access key configuration by ID.
# List AI Gateway access key configurations
Source: https://ngrok.com/docs/ai-gateway/api-reference/access-key-configurations/list
openapi/ai-gateway.yaml GET /access-key-configurations
List all AI Gateway access key configurations owned by the authenticated account.
# Update an AI Gateway access key configuration
Source: https://ngrok.com/docs/ai-gateway/api-reference/access-key-configurations/update
openapi/ai-gateway.yaml PATCH /access-key-configurations/{id}
Apply a partial update to an AI Gateway access key configuration.
# Create an AI Gateway access key
Source: https://ngrok.com/docs/ai-gateway/api-reference/access-keys/create
openapi/ai-gateway.yaml POST /access-keys
Create a new ngrok-managed access key for AI Gateway traffic.
# Delete an AI Gateway access key
Source: https://ngrok.com/docs/ai-gateway/api-reference/access-keys/delete
openapi/ai-gateway.yaml DELETE /access-keys/{id}
Delete an AI Gateway access key by ID.
# Get an AI Gateway access key
Source: https://ngrok.com/docs/ai-gateway/api-reference/access-keys/get
openapi/ai-gateway.yaml GET /access-keys/{id}
Get a single AI Gateway access key by ID.
# List AI Gateway access keys
Source: https://ngrok.com/docs/ai-gateway/api-reference/access-keys/list
openapi/ai-gateway.yaml GET /access-keys
List all AI Gateway access keys owned by the authenticated account.
# Update an AI Gateway access key
Source: https://ngrok.com/docs/ai-gateway/api-reference/access-keys/update
openapi/ai-gateway.yaml PATCH /access-keys/{id}
Update mutable fields on an existing AI Gateway access key.
# Create an AI Gateway API key
Source: https://ngrok.com/docs/ai-gateway/api-reference/api-keys/create
openapi/ai-gateway.yaml POST /api-keys
Create a new AI Gateway API key for the authenticated account.
# Delete an AI Gateway API key
Source: https://ngrok.com/docs/ai-gateway/api-reference/api-keys/delete
openapi/ai-gateway.yaml DELETE /api-keys/{id}
Delete an AI Gateway API key by ID.
# Get an AI Gateway API key
Source: https://ngrok.com/docs/ai-gateway/api-reference/api-keys/get
openapi/ai-gateway.yaml GET /api-keys/{id}
Get a single AI Gateway API key by ID.
# List AI Gateway API keys
Source: https://ngrok.com/docs/ai-gateway/api-reference/api-keys/list
openapi/ai-gateway.yaml GET /api-keys
List all AI Gateway API keys owned by the authenticated account.
# Update an AI Gateway API key
Source: https://ngrok.com/docs/ai-gateway/api-reference/api-keys/update
openapi/ai-gateway.yaml PATCH /api-keys/{id}
Update mutable fields on an existing AI Gateway API key.
# Get credit balance
Source: https://ngrok.com/docs/ai-gateway/api-reference/credits/balance
openapi/ai-gateway.yaml GET /credits/balance
Get the account's current AI Gateway credit balance. Eventually consistent with usage events.
# Create a Stripe checkout session
Source: https://ngrok.com/docs/ai-gateway/api-reference/credits/checkout-session
openapi/ai-gateway.yaml POST /credits/checkout-session
Create a Stripe-hosted checkout session to purchase AI Gateway credits.
# Start a credit purchase
Source: https://ngrok.com/docs/ai-gateway/api-reference/credits/purchase-create
openapi/ai-gateway.yaml POST /credits/purchases
Start an off-session charge of the account's saved card to buy AI Gateway credits, then poll the purchase for its terminal outcome.
# Get a credit purchase
Source: https://ngrok.com/docs/ai-gateway/api-reference/credits/purchase-get
openapi/ai-gateway.yaml GET /credits/purchases/{id}
Get one credit purchase attempt by ID to poll it to a terminal state and read the decline reason recorded on failure.
# List credit transactions
Source: https://ngrok.com/docs/ai-gateway/api-reference/credits/transactions
openapi/ai-gateway.yaml GET /credits/transactions
Returns a merged, date-descending list of credit purchases and metered usage invoices for the account. Read from the billing provider in real time.
# Get AI Gateway configuration
Source: https://ngrok.com/docs/ai-gateway/api-reference/gateway-config/get
openapi/ai-gateway.yaml GET /gateway-config
Get the AI Gateway configuration for the authenticated account.
# Update AI Gateway configuration
Source: https://ngrok.com/docs/ai-gateway/api-reference/gateway-config/update
openapi/ai-gateway.yaml PATCH /gateway-config
Update the AI Gateway configuration for the authenticated account. Omitted fields preserve their existing stored value.
# List available AI Gateway models
Source: https://ngrok.com/docs/ai-gateway/api-reference/models/list
openapi/ai-gateway.yaml GET /v1/models
List every model available to your account, including built-in catalog models and your own user-defined provider models.
# AI Gateway API
Source: https://ngrok.com/docs/ai-gateway/api-reference/overview
Set up and run your AI Gateway from your own code with the management API.
***
The ngrok.ai API lets you manage ngrok.ai directly from your code, so you don't have to rely on the dashboard.
You can use it to create access keys, add provider keys, set up routing and access rules, register custom providers, check usage, and keep an eye on your credit balance.
Note, that the API doesn't handle model requests itself. To call models, send your requests to `https://gateway.ngrok.ai` using an access key.
## Base URL
When you make requests to the ngrok.ai API, send them to:
```text theme={null}
https://api.ngrok.ai
```
Note that the ngrok.ai API uses JSON for both requests and responses, and all calls must be made over HTTPS.
## Authentication
To authenticate, include your [ngrok.ai API key](/docs/ai-gateway/concepts/access-keys#credentials-overview) in the `Authorization` header of each request:
```bash theme={null}
curl https://api.ngrok.ai/access-keys \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY"
```
You can create and manage your ngrok.ai API key on the settings page in the dashboard. Treat this key like a secret, since it allows you to manage the resources in your account.
## OpenAPI spec
The API is described by a public OpenAPI 3.0 spec. Use it to generate a client in any language, or load it into your API tooling:
```text theme={null}
https://api.ngrok.ai/openapi.yaml
```
## What you can manage
Use the AI Gateway API to manage:
* [Access keys](/docs/ai-gateway/api-reference/access-keys/list): Manage keys for making gateway requests
* [Access key configurations](/docs/ai-gateway/api-reference/access-key-configurations/list): Manage access controls and rules for which providers, models, and keys an access key can use
* [Providers](/docs/ai-gateway/api-reference/providers/list): Manage which providers the gateway can route to
* [Provider keys](/docs/ai-gateway/api-reference/provider-keys/list): Manage your credentials for providers
* [API keys](/docs/ai-gateway/api-reference/api-keys/list): Manage keys that grant ngrok.ai API access
* [Configuration](/docs/ai-gateway/api-reference/gateway-config/get): Manage your account level gateway settings
* [Credits](/docs/ai-gateway/api-reference/credits/balance): View your credit balance and transactions, and start a purchase
* [Models](/docs/ai-gateway/api-reference/models/list): List every model your account can reach, with pricing and provider metrics
* [Usage](/docs/ai-gateway/api-reference/usage/list): View data on requests, tokens, providers, models, and costs
## Common workflows
Use the ngrok.ai API to automate common setup and operational tasks.
### Create access keys
Create access keys for applications, environments, teams, or customers. Each access key can have its own configuration for routing, model access, and provider credentials.
### Add provider keys
Store upstream provider credentials so ngrok.ai can call providers on your behalf without exposing those credentials in your application code.
### Configure routing and access
Define access key configurations to control which providers and models an access key can call, and which provider keys are used for upstream authentication.
### Register custom providers
Create custom providers for self-hosted models, private deployments, or other OpenAI-compatible and Anthropic-compatible APIs.
### Monitor usage and credits
Query usage and credit data to track requests, tokens, costs, and remaining balance.
## Next steps
* [Access keys](/docs/ai-gateway/api-reference/access-keys/list): Create and manage access keys
* [Provider keys](/docs/ai-gateway/api-reference/provider-keys/list): Add and rotate upstream provider credentials
* [Access key configurations](/docs/ai-gateway/api-reference/access-key-configurations/list): Configure access, routing, and credential selection
* [Providers](/docs/ai-gateway/api-reference/providers/list): Manage built-in and custom providers
* [Usage](/docs/ai-gateway/api-reference/usage/list): Query request usage
# Create an AI Gateway provider key
Source: https://ngrok.com/docs/ai-gateway/api-reference/provider-keys/create
openapi/ai-gateway.yaml POST /provider-keys
Create a new AI Gateway provider key for your account. Reference it from an access key configuration's routing rule steps to use it.
# Delete an AI Gateway provider key
Source: https://ngrok.com/docs/ai-gateway/api-reference/provider-keys/delete
openapi/ai-gateway.yaml DELETE /provider-keys/{id}
Delete an AI Gateway provider key by ID.
# Get an AI Gateway provider key
Source: https://ngrok.com/docs/ai-gateway/api-reference/provider-keys/get
openapi/ai-gateway.yaml GET /provider-keys/{id}
Get a single AI Gateway provider key by ID.
# List AI Gateway provider keys
Source: https://ngrok.com/docs/ai-gateway/api-reference/provider-keys/list
openapi/ai-gateway.yaml GET /provider-keys
List all AI Gateway provider keys owned by the authenticated account.
# Rotate an AI Gateway provider key
Source: https://ngrok.com/docs/ai-gateway/api-reference/provider-keys/rotate
openapi/ai-gateway.yaml POST /provider-keys/{id}/rotate
Update an AI Gateway provider key by ID to a new value.
# Update an AI Gateway provider key
Source: https://ngrok.com/docs/ai-gateway/api-reference/provider-keys/update
openapi/ai-gateway.yaml PATCH /provider-keys/{id}
Update mutable fields on an existing AI Gateway provider key.
# Create an AI Gateway provider
Source: https://ngrok.com/docs/ai-gateway/api-reference/providers/create
openapi/ai-gateway.yaml POST /providers
Create a new user-defined AI Gateway provider for routing requests to a self-hosted or third-party LLM endpoint.
# Delete an AI Gateway provider
Source: https://ngrok.com/docs/ai-gateway/api-reference/providers/delete
openapi/ai-gateway.yaml DELETE /providers/{id}
Delete an AI Gateway provider and all of its models. Deletion is blocked while a provider key or access key configuration references the provider.
# Get an AI Gateway provider
Source: https://ngrok.com/docs/ai-gateway/api-reference/providers/get
openapi/ai-gateway.yaml GET /providers/{id}
Get a single AI Gateway provider by ID.
# List AI Gateway providers
Source: https://ngrok.com/docs/ai-gateway/api-reference/providers/list
openapi/ai-gateway.yaml GET /providers
List all user-defined AI Gateway providers for the authenticated account. Built-in providers come from the ngrok.ai catalog, not this resource.
# Update an AI Gateway provider
Source: https://ngrok.com/docs/ai-gateway/api-reference/providers/update
openapi/ai-gateway.yaml PATCH /providers/{id}
Apply a partial update to an AI Gateway provider. The providerId is immutable after creation.
# List AI Gateway usage events
Source: https://ngrok.com/docs/ai-gateway/api-reference/usage/list
openapi/ai-gateway.yaml GET /usage
List per-attempt AI Gateway usage events for the authenticated account.
# AI Gateway usage overview
Source: https://ngrok.com/docs/ai-gateway/api-reference/usage/overview
openapi/ai-gateway.yaml GET /usage/overview
Aggregated daily cost, request, and error series for the authenticated account over a time window, grouped by provider or access key.
# Get the upstream attempts of one AI Gateway request
Source: https://ngrok.com/docs/ai-gateway/api-reference/usage/request-attempts
openapi/ai-gateway.yaml GET /usage/requests/{requestId}
Get every upstream attempt the AI Gateway made for one client request, ordered by attempt number.
# Changelog
Source: https://ngrok.com/docs/ai-gateway/changelog
AI Gateway feature updates and changes.
## Never run out of credits
Turn on automatic top-up and ngrok.ai refills your balance from your saved card whenever it runs low. You choose when it tops up and how much, and you can cap how much it spends each billing period.
See [Automatic top-up](/docs/ai-gateway/concepts/credits#automatic-top-up).
## Approve card payments that need an extra check
Some banks ask you to confirm a payment before it goes through. When that happens while you buy credits, you now get a link to approve the payment, and your credits arrive once you do.
See [Credits](/docs/ai-gateway/concepts/credits#purchasing-credits).
## Requests can be up to 32 MiB
Requests larger than 32 MiB are now turned away with a clear error, before they reach a provider.
Most requests are far below this. If you hit it, trim long conversation history or large embedded documents.
## Know when a setting didn't reach the model
Not every model supports every setting. When the gateway has to leave a setting out because the model can't use it, the response now tells you which ones.
See [Response headers](/docs/ai-gateway/how-it-works#response-headers).
## Long answers no longer get cut off
Streaming responses can now keep going for up to 15 minutes, which helps with long answers and slow reasoning models.
If you've set your own total timeout, it still applies.
See [Streaming responses](/docs/ai-gateway/guides/account-settings#streaming-responses).
## Use more providers without signing up for them
You can now pay with credits for models from Google, DeepSeek, xAI, Moonshot AI, Z.ai, Qwen Cloud, MiniMax, and more, in addition to OpenAI and Anthropic.
You don't need an account or API key with those providers.
The [model catalog](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials) shows which models work this way.
## See why a fallback model didn't run
If a model you listed as a fallback couldn't be used, for example because your access key isn't allowed to call it, the response now names it.
See [Response headers](/docs/ai-gateway/how-it-works#response-headers).
## Follow every retry for a request
You can now look up a single request and see each attempt the gateway made, what happened, and why it moved on.
See [Why a request failed over](/docs/ai-gateway/guides/why-a-request-failed-over).
## Request ID, attempt count, and served model on every response
Gateway responses now state how the request was handled:
* `Ngrok-AIG-Request-Id`: the request's ID, on every response including rejections and errors.
* `Ngrok-AIG-Attempts`: how many upstream attempts the gateway made.
* `Ngrok-AIG-Model`: the upstream model that produced the response.
All three are exposed through CORS, so browser clients can read them.
They are ngrok's own headers, so managed-key and Bring Your Own Keys callers see the same values.
See [Response headers](/docs/ai-gateway/how-it-works#response-headers).
The native Gemini `generateContent` and `streamGenerateContent` surface returns these headers too, where it previously returned only `Content-Type`.
Bodies on that surface are still forwarded byte-for-byte.
## The ai-gateway Traffic Policy action is retired
The AI Gateway no longer runs as a Traffic Policy action on your own endpoint.
A policy that still contains the `ai-gateway` action fails validation with `ERR_NGROK_3820`.
* Send LLM traffic to `https://gateway.ngrok.ai` with an [access key](/docs/ai-gateway/concepts/access-keys), and manage the gateway at [app.ngrok.ai](https://app.ngrok.ai).
* Existing credits were migrated to [app.ngrok.ai](https://app.ngrok.ai) automatically. No action is needed to keep your balance.
* Remove the `ai-gateway` action from any endpoint that still carries it.
* The action's result variables, such as `actions.ngrok.ai_gateway`, are gone. Read the [response headers](/docs/ai-gateway/how-it-works#response-headers) and the [Usage API](/docs/ai-gateway/api-reference/usage/list) instead.
Email [support@ngrok.com](mailto:support@ngrok.com) with questions about a migrated account.
## app.ngrok.ai and gateway.ngrok.ai
Manage your AI Gateway from [app.ngrok.ai](https://app.ngrok.ai) and send traffic to a shared gateway URL:
* Manage [access keys](/docs/ai-gateway/concepts/access-keys), [access key configurations](/docs/ai-gateway/guides/access-key-configurations), provider keys, credits, and settings at **[app.ngrok.ai](https://app.ngrok.ai)**.
* Send LLM traffic from your applications to **`https://gateway.ngrok.ai`** with an access key only—provider keys are stored server-side.
* Updated the [Quickstart](/docs/ai-gateway/quickstart), [Overview](/docs/ai-gateway/overview), [How It Works](/docs/ai-gateway/how-it-works), and [Access Keys](/docs/ai-gateway/concepts/access-keys).
* [Provider keys](/docs/ai-gateway/guides/attaching-provider-keys) are now account-scoped in app.ngrok.ai BYOK.
* Endpoint-based Traffic Policy setup is deprecated.
## AI Gateway API keys & credits
You can now authenticate requests to your AI Gateway with **AI Gateway API Keys**—no provider accounts needed. The AI Gateway manages the provider keys for OpenAI and Anthropic on your behalf. Purchase prepaid credits to fund usage.
* [AI Gateway API Keys](/docs/ai-gateway/concepts/access-keys): Create keys to authenticate requests
* [Credits](/docs/ai-gateway/concepts/credits): Understand pricing and balance management
* [Bring Your Own Keys](/docs/ai-gateway/concepts/bring-your-own-keys): Use your own provider keys for additional providers
* Updated [Quickstart](/docs/ai-gateway/quickstart), [Overview](/docs/ai-gateway/overview), and all [SDK guides](/docs/ai-gateway/sdks) to use AI Gateway API Keys as the primary path
## Native Anthropic SDK support
Use Anthropic's official Python and TypeScript SDKs directly with the AI Gateway. The gateway now supports the native `/v1/messages` API format alongside the OpenAI-compatible format. See the [Anthropic SDK guide](/docs/ai-gateway/sdks/anthropic) for setup instructions.
## Groq provider support
Groq is now a built-in provider. Access Llama and Mixtral models running on Groq's LPU hardware with automatic failover and observability.
## Expanded model catalog
Added new providers to the model catalog: Hyperbolic, InceptionLabs, Inference.net, and OpenRouter. Updated model aliases and provider-specific model IDs for improved compatibility.
## Early access release
Initial Early Access release of the AI Gateway.
### Features
* OpenAI-compatible API for routing requests to multiple AI providers
* Support for OpenAI, Anthropic, Google, and other providers
* Multi-provider failover across models, providers, and API keys
* Multi-key failover per provider
* CEL-based model selection strategies
* Custom provider support via internal endpoints
* Token counting and usage metrics
# Access Keys
Source: https://ngrok.com/docs/ai-gateway/concepts/access-keys
The credential your application uses to authenticate with the AI Gateway.
An **access key** authenticates your application to `https://gateway.ngrok.ai`. Send it with every request—the gateway uses it to verify who is calling and whether the request is allowed through.
## Access keys vs provider keys
The AI Gateway splits authentication into two credentials so your application never handles upstream secrets.
| | Access key | Provider key |
| - | - | - |
| **What it is** | The credential your app sends to the gateway | An upstream API key for OpenAI, Anthropic, or another provider |
| **Where it lives** | In your application | In [app.ngrok.ai](https://app.ngrok.ai), attached through an [access key configuration](/docs/ai-gateway/guides/access-key-configurations) |
| **Who uses it** | Your code, as the SDK's `api_key` | The AI Gateway, injected server-side on each request |
Because the two are separate, you can rotate or revoke an access key for one client without touching your [provider keys](/docs/ai-gateway/guides/attaching-provider-keys), and your upstream secrets never ship in client code.
Many built-in providers, including **OpenAI**, **Anthropic**, **Google**, and **DeepSeek**, let you [pay with credits](/docs/ai-gateway/guides/pay-with-credits). There are no provider keys to store at all.
See [How It Works](/docs/ai-gateway/how-it-works) for the full request flow.
## Use in your application
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
```
See the [Quickstart](/docs/ai-gateway/quickstart) to create your first key.
## Create and manage keys
Create a separate key per application or team so you can revoke one client without affecting others.
### Via the ngrok dashboard
1. Open [app.ngrok.ai](https://app.ngrok.ai) → **Keys**.
2. Click **New access key**.
3. Enter a name and optionally assign a configuration.
4. Copy the token immediately—it's only shown once.
### Via the AI Gateway API
1. Create an [AI Gateway API key](#credentials-overview).
2. Send a request to the [Access Keys API](/docs/ai-gateway/api-reference/access-keys/create), authorized with that key:
```bash theme={null}
curl -X POST https://api.ngrok.ai/access-keys \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Production web app" }'
```
## Things to know
### Your key token is only shown once
When you create a key, the token (starting with `ng-`) is displayed exactly once. If you lose it, delete the key and create a new one.
### Requests require credits
Every request consumes [credits](/docs/ai-gateway/concepts/credits) for the ngrok.ai processing fee. When you pay with credits, credits also cover model cost. When you bring your own key, model costs go to your provider account.
When your balance reaches zero, new requests fail until you purchase more credits.
### Invalid keys are rejected
Malformed or deleted access keys are rejected immediately with a `401 Unauthorized`. See [Error Codes](/docs/ai-gateway/reference/error-codes) to look up that and other gateway responses.
## Credentials overview
| Credential | What it's for |
| - | - |
| **ngrok.ai access keys** | Authenticate AI requests to `gateway.ngrok.ai` (required) |
| **ngrok.ai API keys** | Automate AI Gateway resources via `api.ngrok.ai` |
| **ngrok API keys** | Manage ngrok platform resources via the [ngrok API](https://api.ngrok.com) |
| **Your provider keys** | Upstream credentials. See [Bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys) |
## Next steps
Scope providers and route traffic per key
Store upstream credentials
Per-client keys and revocation
How usage is billed
# Bring Your Own Keys
Source: https://ngrok.com/docs/ai-gateway/concepts/bring-your-own-keys
Use your own provider API keys with the AI Gateway.
Bringing your own keys is necessary when:
* you want upstream billing on your provider account
* you need a built-in provider you [can't pay for with credits](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials)
* you're running [custom providers](/docs/ai-gateway/concepts/custom-providers)
Your application authenticates with an [access key](/docs/ai-gateway/concepts/access-keys). Store provider keys in [app.ngrok.ai](https://app.ngrok.ai) and attach them through an [access key configuration](/docs/ai-gateway/guides/access-key-configurations).
## Built-in providers
| | Providers you can pay for with credits | Other built-in providers |
| - | - | - |
| Provider account needed | Optional | Yes |
| Default credentials | ngrok.ai supplies the key, paid with credits | Provider key required in configuration |
| What credits pay for | Processing fee; plus model cost when you pay with credits | Processing fee only |
For providers you can pay for with credits, create a configuration routing rule with **Bring your own API key** instead of **ngrok** when you want to use your provider account.
## Custom providers
Custom providers are endpoints you define, such as Ollama, vLLM, or any OpenAI- or Anthropic-compatible API. See [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself).
Custom providers require provider keys in the configuration when the upstream needs authentication. See [Custom providers](/docs/ai-gateway/concepts/custom-providers).
## Setup flow
1. [Add provider keys](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key).
2. Create an [access key configuration](/docs/ai-gateway/guides/access-key-configurations) with routing rules and scope.
3. Assign the configuration to an [access key](/docs/ai-gateway/concepts/access-keys).
4. Send requests with the access key only.
## Guides
Store upstream credentials
Attach keys and set scope
Self-hosted and third-party endpoints
# Credits
Source: https://ngrok.com/docs/ai-gateway/concepts/credits
Understanding AI Gateway credits, pricing, and balance management.
AI Gateway credits are a prepaid balance you buy in [app.ngrok.ai](https://app.ngrok.ai). Every request through `https://gateway.ngrok.ai` pays a small [processing fee](#processing-fee) from your credits. If you don't use your own provider key, credits also pay for the model. See [How credits are consumed](#how-credits-are-consumed).
## Accounts and plans
You don't need an ngrok subscription to use the AI Gateway. Sign in to [app.ngrok.ai](https://app.ngrok.ai) with your ngrok account, buy credits, and create an [access key](/docs/ai-gateway/concepts/access-keys).
AI Gateway credits are separate from your ngrok plan. Your ngrok plan doesn't pay for AI Gateway usage, and credits don't pay for other ngrok features.
| Manage | Where |
| - | - |
| Access keys, providers, credits, and usage | [app.ngrok.ai](https://app.ngrok.ai) |
| Your ngrok plan, team members, tunnels, and endpoints | [dashboard.ngrok.com](https://dashboard.ngrok.com) |
To reach a model you run yourself through an [internal endpoint](/docs/ai-gateway/concepts/custom-providers), set up the endpoint in dashboard.ngrok.com. Some ngrok features need a paid plan; see [pricing](https://ngrok.com/pricing).
## Purchasing credits
1. Open the [Billing page](https://app.ngrok.ai/billing) and select **Add credits**. If you haven't saved a card yet, you'll add one first.
2. Pick an amount, or enter your own. The minimum is \$5, and your balance can be at most \$500.
3. Select **Buy** to confirm.
To buy credits from code, use the [Credits API](/docs/ai-gateway/api-reference/credits/purchase-create).
Credits expire **one year** after purchase.
## Automatic top-up
Automatic top-up adds credits from your saved card when your balance runs low.
To set it up:
1. Open the [Billing page](https://app.ngrok.ai/billing) and make sure you have a saved card.
2. Select **Enable auto top-up**, then turn on **Enable auto top-up** in the dialog.
3. Set **When your balance reaches** (at least \$5) and **Top up to** (up to \$500).
4. Optional: select **Set a spending limit** and enter a **Maximum spend every billing period**.
5. Select **Save changes**.
## How credits are consumed
| If the request uses | Credits pay for | You pay separately |
| - | - | - |
| An ngrok.ai key | Processing fee and model usage, including hosted tools like web search | Nothing |
| Your own provider key | Processing fee | Model usage, billed by your provider |
| A model you run yourself | Processing fee | Your own infrastructure |
## Balance tracking
You can view your balance on the [Billing page](https://app.ngrok.ai/billing), or via the API:
```bash theme={null}
curl https://api.ngrok.ai/credits/balance \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY"
```
## What happens when credits run out
When your credit balance reaches zero, the gateway rejects new requests with HTTP 402 and [`ERR_NGROK_27206`](/docs/ai-gateway/reference/error-codes#err_ngrok_27206) until you purchase more credits. That's true even if you use your own provider keys, since every request pays a small processing fee from your credits.
To avoid this, turn on [automatic top-up](#automatic-top-up) so your balance refills before it runs out.
The balance updates shortly after usage, so requests already in flight can take it slightly below zero. The [balance API](/docs/ai-gateway/api-reference/credits/balance) reports a negative value when that happens.
## Processing fee
Every successful request through the gateway incurs a processing fee at **USD \$0.05 per million tokens**. The fee is based on the tokens in your request and response. It applies to all traffic—requests paid with credits, your own [provider keys](/docs/ai-gateway/guides/attaching-provider-keys), and [custom providers](/docs/ai-gateway/concepts/custom-providers)—and does not vary by model or provider. With [`ngrok/auto`](/docs/ai-gateway/guides/automatic-model-selection#billing), the tokens ngrok.ai reads to pick a model also count toward the fee.
When you pay with credits, credits also cover the provider's model cost. When you bring your own key, model costs stay on your provider account and credits cover only the processing fee.
## Next steps
* [Access Keys](/docs/ai-gateway/concepts/access-keys): Authenticate requests to the gateway
* [Quickstart](/docs/ai-gateway/quickstart): Purchase credits and make your first request
* [Bring Your Own Keys](/docs/ai-gateway/concepts/bring-your-own-keys): Use your own provider API keys
# Custom Providers
Source: https://ngrok.com/docs/ai-gateway/concepts/custom-providers
Connect custom endpoints and self-hosted models to the AI Gateway.
**Custom providers** are upstream endpoints you define, such as self-hosted Ollama or vLLM, a private deployment, or any OpenAI- or Anthropic-compatible API not in the [built-in catalog](/docs/ai-gateway/reference/model-catalog).
Use a custom provider when you want the AI Gateway to call a model running on your machine, private network, or cloud GPU.
Traffic still authenticates to the gateway with an [access key](/docs/ai-gateway/concepts/access-keys). Attach provider keys and routing rules through an [access key configuration](/docs/ai-gateway/guides/access-key-configurations).
## When to use one
Use a custom provider when:
* You run models locally with Ollama, LM Studio, or vLLM.
* You host models on your own cloud infrastructure.
* You have a private OpenAI- or Anthropic-compatible API.
* You need a provider that isn't in the built-in catalog.
## What a custom provider defines
A custom provider tells the gateway:
* Which provider ID to use in requests, such as `my-ollama`.
* Which base URL to call, such as `https://my-ollama.internal`.
* Which API surface the endpoint supports.
* Which model IDs are available.
You call custom provider models with the same `provider:model` format as built-in providers:
```json theme={null}
{
"model": "my-ollama:llama3.2",
"messages": [{"role": "user", "content": "Hello"}]
}
```
## URL requirements
| URL type | Scheme | Example |
| - | - | - |
| External | `https://` only | `https://api.example.com/v1` |
| ngrok internal | `http://` or `https://` | `https://my-service.internal` |
HTTP is only allowed for ngrok `.internal` endpoints. External URLs must use HTTPS.
## Self-hosted on a local network
To reach models on your machine or private network, expose the service with an ngrok internal endpoint, then use that URL as the custom provider's `baseUrl`. Reaching internal endpoints may require a ngrok platform plan. See [Credits](/docs/ai-gateway/concepts/credits).
For the full setup flow, see [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself).
## Next steps
* [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself): Connect a local or private model
* [Ollama guide](/docs/ai-gateway/custom-providers/ollama): Connect Ollama
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations): Attach keys and scope access
* [Model catalog](/docs/ai-gateway/reference/model-catalog): Built-in providers and models
# Models
Source: https://ngrok.com/docs/ai-gateway/concepts/models
Understanding model naming and request formats in the AI Gateway.
Models are the AI systems that process your requests. You specify the model in each request body, and you can use an [access key configuration](/docs/ai-gateway/guides/access-key-configurations) to restrict which models an access key may call.
## Specifying models
### Model name only
```json theme={null}
{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}]
}
```
The gateway looks up `gpt-4o` in the [model catalog](/docs/ai-gateway/reference/model-catalog) and routes to OpenAI. If OpenAI fails, it can try other providers that serve the same model.
The full catalog ID, `author/model` such as `openai/gpt-4o`, works the same way.
### Provider prefix
```json theme={null}
{
"model": "anthropic:claude-sonnet-4-6",
"messages": [{"role": "user", "content": "Hello"}]
}
```
Use `provider:model` when you want to force a specific provider or target [a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself).
## Multiple models (failover)
List fallback models with the `models` array:
```json theme={null}
{
"model": "gpt-4o",
"models": ["gpt-4o-mini", "anthropic:claude-sonnet-4-6"],
"messages": [{"role": "user", "content": "Hello"}]
}
```
The gateway tries `model` first, then each entry in `models` in order, until one succeeds.
## Unknown models (pass-through)
If a model is not in the catalog, the gateway still routes it when you include a provider prefix:
```json theme={null}
{
"model": "openai:some-new-model",
"messages": [{"role": "user", "content": "Hello"}]
}
```
The provider returns an error if the model does not exist. Pass-through models must still be allowed by the access key's configuration.
## Model and provider names
Model names are not case-sensitive: `gpt-4o`, `GPT-4o`, and `Gpt-4O` all resolve to the same model. Provider names are matched exactly, so use the lowercase **Provider ID** from the [model catalog](/docs/ai-gateway/reference/model-catalog).
Name models and providers by their primary catalog ID. The gateway does not resolve alternate names for either.
## Model capabilities
Models differ in input/output modalities, context window, and features. See the [model catalog](/docs/ai-gateway/reference/model-catalog) for details.
## Next steps
* [Model catalog](/docs/ai-gateway/reference/model-catalog): Supported models by provider
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Model IDs and provider prefixes
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model when the first one fails
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Limit models per key
# Providers
Source: https://ngrok.com/docs/ai-gateway/concepts/providers
Built-in and custom AI providers in the ngrok AI Gateway.
Providers are the AI services that host and serve models. The AI Gateway routes your requests to providers and handles authentication, failover, and observability.
Manage providers at [app.ngrok.ai](https://app.ngrok.ai). If you're deciding which setup path to use, start with [Choose how to reach providers](/docs/ai-gateway/guides/configuring-providers). The dashboard separates **built-in** catalog providers from **custom** providers you define.
## Built-in providers
Built-in providers are public AI APIs with a known model catalog: OpenAI, Anthropic, Google, Groq, and others listed in the [model catalog](/docs/ai-gateway/reference/model-catalog). You can send requests with an [access key](/docs/ai-gateway/concepts/access-keys). Your access key authenticates you to the gateway, not to the upstream provider.
For many built-in providers, including **OpenAI**, **Anthropic**, **Google**, and **DeepSeek**, the AI Gateway can supply the provider credentials when you have [credits](/docs/ai-gateway/concepts/credits). The [model catalog](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials) shows which providers support it. You aren't required to have your own provider account or provider API keys—the AI Gateway handles upstream authentication and bills model cost through credits.
For providers you can't pay for with credits, [bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key). Model costs go to your provider account; credits still cover the gateway processing fee. This is generally referred to as BYOK (bring your own key).
GPT and o-series models. Pay with credits.
Claude models. Pay with credits. Supports both OpenAI and Anthropic SDK formats.
Access hundreds of models from multiple providers through a single API.
Gemini models from Google AI Studio. Pay with credits.
LPU-accelerated inference for open-source models (GPT-OSS, Llama 4, Qwen3).
High-performance reasoning and chat models. Pay with credits.
Open-source model hosting with high-performance inference.
Diffusion-based language models for fast text generation.
Distributed inference network for AI models at scale.
Grok models. Pay with credits.
Models served by Mistral AI. Bring your own key.
Kimi models. Pay with credits.
GLM models. Pay with credits.
Qwen models and other open models. Pay with credits.
MiniMax models. Pay with credits.
Models from Tencent, DeepSeek, Moonshot AI, Z.ai, MiniMax, and more. Pay with credits.
System One models that answer typed questions. Pay with credits.
## Custom providers
Custom providers are upstream endpoints you define, such as self-hosted Ollama or vLLM, a private deployment, or any OpenAI- or Anthropic-compatible API that isn't in the built-in catalog. See [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself).
Custom providers require a provider key when the upstream needs authentication. See [Custom providers](/docs/ai-gateway/concepts/custom-providers) for the concept.
Run open-source models locally with Ollama.
High-performance inference server.
Desktop app for local model inference.
Microsoft's OpenAI service on Azure.
## How provider selection works
When a request arrives, the gateway determines which provider to use:
1. **Explicit provider prefix**: if the model name includes a provider prefix (for example, `openai:gpt-4o` or `openrouter:anthropic/claude-3.5-sonnet`), that provider is used
2. **Catalog lookup**: the gateway looks up the model ID in its [catalog](/docs/ai-gateway/reference/model-catalog) to find the default provider
3. **Request selection**: [model names](/docs/ai-gateway/guides/model-selection-strategies) and fallback lists can override the default
## Next steps
* [Model Catalog](/docs/ai-gateway/reference/model-catalog): browse all available models by provider
* [Bring Your Own Keys](/docs/ai-gateway/concepts/bring-your-own-keys): add provider keys for built-in and custom providers
* [Multi-provider failover](/docs/ai-gateway/examples/multi-provider-failover): automatic failover across providers
# Azure OpenAI
Source: https://ngrok.com/docs/ai-gateway/custom-providers/azure-openai
Route AI requests to Azure OpenAI Service through the ngrok AI Gateway.
[Azure OpenAI Service](https://azure.microsoft.com/en-us/products/ai-services/openai-service) provides OpenAI models on Microsoft Azure. Connect your deployment to the AI Gateway as a [custom provider](/docs/ai-gateway/concepts/custom-providers).
## What you'll need
* [ngrok account](https://app.ngrok.ai) with AI Gateway access
* [Azure OpenAI Service](https://azure.microsoft.com/en-us/products/ai-services/openai-service) resource with a deployed model
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai)
## Overview
Azure OpenAI uses deployment-specific URLs and requires an `api-version` query parameter. The gateway injects your Azure API key server-side.
```mermaid theme={null}
graph LR
A[Client] --> B[gateway.ngrok.ai]
B --> C[Azure OpenAI]
```
## Getting started
From the Azure Portal, collect:
1. **Resource endpoint**: `https://your-resource.openai.azure.com`
2. **API key**: from **Keys and Endpoint**
3. **Deployment name**: the name of your model deployment
4. **API version**: a supported version (for example `2024-02-15-preview`)
Azure requires the deployment path and `api-version` in the base URL. See [Create a custom provider](/docs/ai-gateway/guides/use-a-model-you-run-yourself#create-a-custom-provider) with:
* **Provider ID**: `azure-openai`
* **Base URL**: `https://your-resource.openai.azure.com/openai/deployments/your-deployment?api-version=2024-02-15-preview`
* **API format**: OpenAI Chat Completions
* **Models**: the model name for this deployment (for example `gpt-4o`)
Include `api-version` as a query parameter on the base URL. Azure rejects requests without it.
[Add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) for your Azure deployment.
Create an [access key configuration](/docs/ai-gateway/guides/access-key-configurations) that:
1. Allows the `azure-openai` provider in the access scope
2. Adds a routing rule for `azure-openai` with **Bring your own API key** and your stored key attached
Assign the configuration to your access key.
```python Python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx"
)
response = client.chat.completions.create(
model="azure-openai:gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
```
```typescript TypeScript theme={null}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx"
});
const response = await client.chat.completions.create({
model: "azure-openai:gpt-4o",
messages: [{ role: "user", content: "Hello!" }]
});
console.log(response.choices[0].message.content);
```
## Multiple deployments and regions
Create a separate custom provider for each Azure deployment or region. Give each a unique provider ID (for example `azure-gpt4`, `azure-eastus`) with its own deployment URL and model list.
Attach the same or different provider keys per deployment. Pin a region with `azure-eastus:gpt-4o`, or list multiple models for failover: `models: ["azure-eastus:gpt-4o", "openai:gpt-4o"]`.
## Troubleshooting
| Symptom | Fix |
| - | - |
| 401 unauthorized | Verify the provider key in app.ngrok.ai matches Azure Portal and is attached in your access key configuration |
| 404 deployment not found | Check the deployment name in the base URL matches Azure Portal |
| API version errors | Update the `api-version` query parameter to a [supported version](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference) |
| 429 rate limiting | Add multiple provider keys for failover or request a quota increase in Azure Portal |
## Next steps
* [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself): URL requirements and configuration
* [Provider Keys](/docs/ai-gateway/guides/attaching-provider-keys): Store upstream credentials
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations): Route traffic per access key
* [Quickstart](/docs/ai-gateway/quickstart): Create your first access key
# LM Studio
Source: https://ngrok.com/docs/ai-gateway/custom-providers/lm-studio
Route AI requests to local LM Studio models through the ngrok AI Gateway.
[LM Studio](https://lmstudio.ai) is a desktop app for running LLMs locally with an [OpenAI-compatible API](https://lmstudio.ai/docs/developer/openai-compat). Connect it to the AI Gateway as a [custom provider](/docs/ai-gateway/concepts/custom-providers).
## What you'll need
* [ngrok account](https://app.ngrok.ai) with AI Gateway access
* [LM Studio](https://lmstudio.ai/download) installed
* [ngrok agent](https://download.ngrok.com) installed
* A model downloaded in LM Studio
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai)
## Overview
LM Studio runs a local HTTP server. Expose it with an ngrok internal endpoint, register the endpoint as a custom provider, then route traffic through the gateway.
```mermaid theme={null}
graph LR
A[Client] --> B[gateway.ngrok.ai]
B --> C[ngrok Internal Endpoint]
C --> D[LM Studio localhost:1234]
```
## Getting started
Download a model and start the server:
1. Open LM Studio and download a model from the **Discover** tab
2. Go to **Developer**, select the model, and click **Start Server**
```bash theme={null}
lms get llama-3.2-3b-instruct@q4_k_m
lms server start
```
By default, LM Studio listens on port `1234`. Verify the server is running:
```bash theme={null}
curl http://localhost:1234/v1/models
```
Use the model ID exactly as LM Studio reports it from `GET /v1/models`.
Create an [internal endpoint](/docs/ai-gateway/guides/use-a-model-you-run-yourself#connect-a-local-model-with-an-internal-endpoint):
```bash theme={null}
ngrok http 1234 --url https://lm-studio.internal
```
Internal endpoints (`.internal` domains) are private to your ngrok account, meaning they're not reachable from the public internet. Use the same ngrok account here and in the AI Gateway, otherwise the gateway can't reach the endpoint.
See [Create a custom provider](/docs/ai-gateway/guides/use-a-model-you-run-yourself#create-a-custom-provider). Use provider ID `lm-studio`, base URL `https://lm-studio.internal`, and your model IDs.
LM Studio doesn't require upstream authentication, so you can skip provider keys.
Create an [access key configuration](/docs/ai-gateway/guides/access-key-configurations) that allows the `lm-studio` provider, then assign it to your access key.
```python Python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx"
)
response = client.chat.completions.create(
model="lm-studio:llama-3.2-3b-instruct",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
```
```typescript TypeScript theme={null}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx"
});
const response = await client.chat.completions.create({
model: "lm-studio:llama-3.2-3b-instruct",
messages: [{ role: "user", content: "Hello!" }]
});
console.log(response.choices[0].message.content);
```
```bash cURL theme={null}
curl https://gateway.ngrok.ai/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ng-xxxxx-g1-xxxxx" \
-d '{
"model": "lm-studio:llama-3.2-3b-instruct",
"messages": [{"role": "user", "content": "Hello!"}]
}'
```
## Tips
* **Embeddings**: The AI Gateway doesn't serve `/v1/embeddings`. Call LM Studio's embeddings endpoint directly.
* **Slow first response**: Pre-load the model in LM Studio or enable "Keep model in memory" in settings. Increase `perRequestTimeout` in [account settings](/docs/ai-gateway/guides/account-settings) if needed.
* **Cloud fallback**: Add a built-in provider to your access key configuration and use `models: ["lm-studio:llama-3.2-3b-instruct", "openai:gpt-4o"]` for failover.
## Troubleshooting
| Symptom | Fix |
| - | - |
| Connection refused | Confirm the LM Studio server is running and the ngrok tunnel is active |
| Model not found | Check `curl http://localhost:1234/v1/models` and match the model ID exactly |
| Out of memory | Use a smaller model or lower quantization (Q4 instead of Q8) |
| Port in use | Change the port in LM Studio settings and update your ngrok command |
## Next steps
* [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself): URL requirements and local networking
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations): Scope providers per key
* [Quickstart](/docs/ai-gateway/quickstart): Create your first access key
# Ollama
Source: https://ngrok.com/docs/ai-gateway/custom-providers/ollama
Route AI requests to local Ollama models through the ngrok AI Gateway.
[Ollama](https://ollama.ai) runs open-source large language models locally. This guide shows you how to connect Ollama to the ngrok AI Gateway as a [custom provider](/docs/ai-gateway/concepts/custom-providers).
## What you'll need
* [ngrok account](https://app.ngrok.ai) with AI Gateway access
* [Ollama](https://ollama.ai/download) installed locally
* [ngrok agent](https://download.ngrok.com) installed
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai)
## Overview
Ollama runs on HTTP locally. Expose it with an ngrok internal endpoint, register the endpoint as a custom provider, then route traffic through the gateway.
```mermaid theme={null}
graph LR
A[Client] --> B[gateway.ngrok.ai]
B --> C[ngrok Internal Endpoint]
C --> D[Ollama localhost:11434]
```
## Getting started
Start the Ollama server:
```bash theme={null}
ollama serve
```
Pull a model if you haven't already:
```bash theme={null}
ollama pull llama3.2
```
Verify Ollama is running:
```bash theme={null}
curl http://localhost:11434/api/tags
```
Create an [internal endpoint](/docs/ai-gateway/guides/use-a-model-you-run-yourself#connect-a-local-model-with-an-internal-endpoint) with the [ngrok agent](/docs/gateway/agent/):
```bash theme={null}
ngrok http 11434 --url https://ollama.internal
```
Internal endpoints (`.internal` domains) are private to your ngrok account, meaning they're not reachable from the public internet. Use the same ngrok account here and in the AI Gateway, otherwise the gateway can't reach the endpoint.
See [Create a custom provider](/docs/ai-gateway/guides/use-a-model-you-run-yourself#create-a-custom-provider). Use provider ID `ollama`, base URL `https://ollama.internal`, and your model IDs (for example `llama3.2`).
Ollama doesn't require upstream authentication, so you can skip provider keys.
Create an [access key configuration](/docs/ai-gateway/guides/access-key-configurations) that allows your `ollama` provider, then assign it to your access key. See the [Quickstart](/docs/ai-gateway/quickstart) if you haven't created an access key yet.
Point any OpenAI-compatible SDK at the gateway using your access key:
```python Python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx"
)
response = client.chat.completions.create(
model="ollama:llama3.2",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
```
```typescript TypeScript theme={null}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx"
});
const response = await client.chat.completions.create({
model: "ollama:llama3.2",
messages: [{ role: "user", content: "Hello!" }]
});
console.log(response.choices[0].message.content);
```
```bash cURL theme={null}
curl https://gateway.ngrok.ai/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ng-xxxxx-g1-xxxxx" \
-d '{
"model": "ollama:llama3.2",
"messages": [{"role": "user", "content": "Hello!"}]
}'
```
## Tips
* **Slow first response**: Ollama loads models into memory on first use. Increase `perRequestTimeout` in [account settings](/docs/ai-gateway/guides/account-settings) if requests time out during warm-up.
* **Multiple instances**: Create separate custom providers (for example `ollama-gpu-1`, `ollama-gpu-2`) with different internal endpoints. Pin a request with `ollama-gpu-1:llama3.2` or list multiple models for failover.
* **Cloud fallback**: Add a built-in provider to your access key configuration and request `models: ["ollama:llama3.2", "openai:gpt-4o"]` for cross-provider failover. See [Multi-provider failover](/docs/ai-gateway/examples/multi-provider-failover).
## Troubleshooting
| Symptom | Fix |
| - | - |
| Connection refused | Confirm Ollama is running (`curl http://localhost:11434/api/tags`) and the ngrok tunnel is active |
| Model not found | Run `ollama list`, pull the model, and match the model ID exactly (including tags like `:1b`) |
| Out of memory | Use a smaller or quantized model, or set `OLLAMA_NUM_PARALLEL=1` |
## Next steps
* [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself): URL requirements and local networking
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations): Scope providers per key
* [Quickstart](/docs/ai-gateway/quickstart): Create your first access key
# vLLM
Source: https://ngrok.com/docs/ai-gateway/custom-providers/vllm
Route AI requests to vLLM inference servers through the ngrok AI Gateway.
[vLLM](https://github.com/vllm-project/vllm) is a high-performance inference engine with an OpenAI-compatible API. Connect your vLLM server to the AI Gateway as a [custom provider](/docs/ai-gateway/concepts/custom-providers).
## What you'll need
* [ngrok account](https://app.ngrok.ai) with AI Gateway access
* [vLLM](https://docs.vllm.ai/en/latest/getting_started/installation.html) installed
* [ngrok agent](https://download.ngrok.com) installed
* GPU with sufficient VRAM for your chosen model
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai)
## Overview
vLLM provides an OpenAI-compatible server that you can expose with an ngrok internal endpoint (or use a public HTTPS URL), register as a custom provider, and attach credentials through an access key configuration.
```mermaid theme={null}
graph LR
A[Client] --> B[gateway.ngrok.ai]
B --> C[ngrok Internal Endpoint]
C --> D[vLLM Server :8000]
```
## Getting started
Start the OpenAI-compatible server:
```bash theme={null}
vllm serve meta-llama/Llama-3.2-8B-Instruct
```
Verify it's running:
```bash theme={null}
curl http://localhost:8000/v1/models
```
Create an [internal endpoint](/docs/ai-gateway/guides/use-a-model-you-run-yourself#connect-a-local-model-with-an-internal-endpoint):
```bash theme={null}
ngrok http 8000 --url https://vllm.internal
```
If vLLM already has a public HTTPS endpoint, skip this step and use that URL as the provider base URL instead.
See [Create a custom provider](/docs/ai-gateway/guides/use-a-model-you-run-yourself#create-a-custom-provider). Use provider ID `vllm`, base URL `https://vllm.internal`, API format **OpenAI Chat Completions**, and your model IDs.
If your vLLM server requires an API key (`vllm serve model --api-key your-secret-key`), [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key).
Create an [access key configuration](/docs/ai-gateway/guides/access-key-configurations) that:
1. Allows the `vllm` provider in the access scope
2. Adds a routing rule with **Bring your own API key** if the server requires authentication
Assign the configuration to your access key.
```python Python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx"
)
response = client.chat.completions.create(
model="vllm:meta-llama/Llama-3.2-8B-Instruct",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
```
```typescript TypeScript theme={null}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx"
});
const response = await client.chat.completions.create({
model: "vllm:meta-llama/Llama-3.2-8B-Instruct",
messages: [{ role: "user", content: "Hello!" }]
});
console.log(response.choices[0].message.content);
```
## Tips
* **Secure vLLM**: Run with `--api-key` and attach the key through an [access key configuration](/docs/ai-gateway/guides/access-key-configurations). The AI Gateway adds it to upstream requests server-side.
* **Gated models**: Set `HF_TOKEN` before starting vLLM for Hugging Face gated models.
* **Timeouts**: Large models can be slow. Increase `perRequestTimeout` and `totalTimeout` in [account settings](/docs/ai-gateway/guides/account-settings).
* **Multiple models**: Run separate vLLM instances with different internal endpoints and register each as its own custom provider.
## Troubleshooting
| Symptom | Fix |
| - | - |
| Model loading errors | Check GPU memory with `nvidia-smi`; try `--gpu-memory-utilization 0.9` or a smaller model |
| Connection timeouts | Verify the ngrok tunnel and vLLM health (`curl http://localhost:8000/health`); increase gateway timeouts |
| 401 unauthorized | Confirm the provider key in app.ngrok.ai matches your vLLM `--api-key` and is attached in the access key configuration |
## Next steps
* [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself): URL requirements and configuration
* [Provider Keys](/docs/ai-gateway/guides/attaching-provider-keys): Store upstream credentials
* [Quickstart](/docs/ai-gateway/quickstart): Create your first access key
# Restrict Models and Providers
Source: https://ngrok.com/docs/ai-gateway/examples/model-filtering
Limit which models and providers an access key can call.
Use an [access key configuration](/docs/ai-gateway/guides/access-key-configurations) to restrict providers and models. Requests outside the allowlist are rejected before they reach an upstream provider.
## Allow specific providers
```json theme={null}
{
"name": "OpenAI only",
"access": {
"providers": { "allow": ["openai"] }
},
"router": {
"rules": [
{ "provider": "openai", "steps": [{ "type": "ngrok" }] }
]
}
}
```
Assign this configuration to an access key. That key can only reach OpenAI models.
## Allow specific models
```json theme={null}
{
"name": "Cheap models only",
"access": {
"models": {
"allow": ["openai/gpt-4o-mini", "anthropic/claude-haiku-4-5"]
}
}
}
```
Model IDs use the catalog form `author/model`, as shown in the [model catalog](/docs/ai-gateway/reference/model-catalog). This form matches the model on every provider that serves it. To pin a provider, prefix it: `openai:openai/gpt-4o`. See [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models#allow-specific-models).
## Block pass-through models
If clients use provider prefixes for uncatalogued models, include only known model IDs in the allowlist. Requests for models not listed are rejected.
## Via dashboard
Follow [Create a configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) in [app.ngrok.ai](https://app.ngrok.ai) to set allowed providers and models, then assign the configuration to your access keys.
## Next steps
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations): Full reference
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Model IDs and provider prefixes
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Limit models per key
* [Securing Your Gateway](/docs/ai-gateway/guides/securing-endpoints): Per-client keys
# Multi-Key Failover
Source: https://ngrok.com/docs/ai-gateway/examples/multi-key-failover
Configure multiple provider keys for automatic failover across rate limits and errors.
Add multiple provider keys to the same routing rule in an [access key configuration](/docs/ai-gateway/guides/access-key-configurations). The gateway tries keys in order when one hits a rate limit or an auth error.
Your application sends only an [access key](/docs/ai-gateway/concepts/access-keys)—provider keys are stored in app.ngrok.ai and referenced by the configuration.
## Setup
1. [Add two or more provider keys](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) for the same provider
2. Create or edit a configuration with an ordered `user` step listing both key IDs
3. Assign the configuration to your access key
```json theme={null}
{
"router": {
"rules": [
{
"provider": "openai",
"steps": [
{
"type": "user",
"keySelectionStrategy": "ordered",
"keys": [
{ "id": "aigpk_primary" },
{ "id": "aigpk_backup" }
]
}
]
}
]
}
}
```
## Failover sequence
```
1. Request arrives with access key
2. Try primary OpenAI key → Rate limited (429)
3. Try backup OpenAI key → Success
```
## Next steps
* [Multi-key failover guide](/docs/ai-gateway/guides/key-selection-failover): Full details
* [Bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys): Store credentials
* [Multi-provider failover](/docs/ai-gateway/examples/multi-provider-failover): Fail over across providers
# Multi-Provider Failover
Source: https://ngrok.com/docs/ai-gateway/examples/multi-provider-failover
Fail over between models and providers in AI Gateway requests.
You can configure fail over by listing multiple models in a request. The gateway tries each model in order until one succeeds. Combine this with an [access key configuration](/docs/ai-gateway/guides/access-key-configurations) that allows the providers you need.
Your app sends an [access key](/docs/ai-gateway/concepts/access-keys); the AI Gateway routes to each provider with the credentials from your configuration.
## Basic example
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="gpt-4o",
extra_body={
"models": ["anthropic:claude-sonnet-4-6"],
},
messages=[{"role": "user", "content": "Hello!"}],
)
```
Or in raw JSON:
```json theme={null}
{
"model": "gpt-4o",
"models": ["anthropic:claude-sonnet-4-6"],
"messages": [{"role": "user", "content": "Hello"}]
}
```
## How it works
1. Request arrives with your access key
2. Gateway tries `gpt-4o` (OpenAI)
3. On failure, tries `anthropic:claude-sonnet-4-6`
4. Returns the first successful response
Both providers must be allowed by the access key's configuration, with routing rules that supply credentials (pay with credits or provider keys).
## Configuration example
Allow OpenAI and Anthropic on one key:
```json theme={null}
{
"name": "Multi-provider production",
"access": {
"providers": { "allow": ["openai", "anthropic"] }
},
"router": {
"rules": [
{ "provider": "openai", "steps": [{ "type": "ngrok" }] },
{ "provider": "anthropic", "steps": [{ "type": "ngrok" }] }
]
}
}
```
Use provider keys instead of `ngrok` steps when billing should go to your provider accounts.
## Next steps
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Model IDs and provider prefixes
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Fallback ordering and access rules
* [Multi-key failover](/docs/ai-gateway/guides/key-selection-failover): Fail over between provider keys
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations): Scope and routing
# FAQ
Source: https://ngrok.com/docs/ai-gateway/faq
Frequently asked questions about ngrok.ai.
***
## Getting started
### What URL do I send requests to?
Send model requests to `https://gateway.ngrok.ai`.
If you are using an OpenAI-compatible SDK, set the base URL to:
```text theme={null}
https://gateway.ngrok.ai/v1
```
For example:
```typescript theme={null}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx"
});
```
See the [Quickstart](/docs/ai-gateway/quickstart) for a full example.
### Can I use my existing OpenAI SDK?
Yes. The AI Gateway supports OpenAI-compatible requests, so you can usually keep your SDK and change the base URL and API key.
Use your ngrok.ai access key as the API key, and set the base URL to `https://gateway.ngrok.ai/v1`.
See [SDK Integration](/docs/ai-gateway/sdks) for examples.
### Do I need a provider account to use ngrok.ai?
Not always.
For many providers, including OpenAI, Anthropic, Google, and DeepSeek, you can skip adding your own provider key and pay with credits instead.
For other built-in providers, or if you want usage billed to your own provider account, you can add a provider key.
### Do I need credits?
Yes. Every request through ngrok.ai require credits for the gateway processing fee.
If ngrok.ai supplies the upstream provider credentials, credits also pay the upstream model cost. If you bring your own provider key, the provider bills you for model usage and credits only pay the gateway processing fee.
See [Credits](/docs/ai-gateway/concepts/credits).
### Do I need a ngrok subscription plan?
No, not to use the AI Gateway itself. You can sign in at [app.ngrok.ai](https://app.ngrok.ai), purchase AI Gateway credits, create an access key, and send requests to `https://gateway.ngrok.ai`.
You may need a ngrok platform plan for platform features on the same account, such as team members or internal endpoints for custom providers. Manage those features from [dashboard.ngrok.com](https://dashboard.ngrok.com).
See [Credits](/docs/ai-gateway/concepts/credits).
### Can my team sign in with SSO?
Yes. app.ngrok.ai uses your ngrok account to sign in, so it uses your account's single sign-on (SAML or OpenID Connect, with providers like Okta).
SSO requires the Pay-as-you-go plan with the SSO & RBAC add-on. Set it up on your [ngrok account settings](https://dashboard.ngrok.com/settings). See [Dashboard Single Sign-On](/docs/iam/sso).
Role-based permissions inside app.ngrok.ai aren't available yet.
## Keys and credentials
### Which key do I put in my app?
Use an access key.
Your app sends the access key to `https://gateway.ngrok.ai`. Do not put provider keys, ngrok API keys, or AI Gateway API keys in your app's model requests.
See [Access keys](/docs/ai-gateway/concepts/access-keys).
### What is the difference between access keys, provider keys, AI Gateway API keys, and ngrok API keys?
| Key | Used for |
| - | - |
| Access key | Authenticates model requests to `gateway.ngrok.ai` |
| Provider key | Authenticates ngrok.ai to an upstream provider |
| AI Gateway API key | Automates AI Gateway resources through `api.ngrok.ai` |
| ngrok API key | Manages ngrok platform resources through `api.ngrok.com` |
Most applications only need an access key in runtime code.
### What are access keys?
Access keys are what your app uses to authenticate model requests to `https://gateway.ngrok.ai`.
It’s a good idea to create separate access keys for different applications, environments, or teams so you can easily track usage, control access, and revoke keys if needed.
### Can I create multiple access keys?
Yes, you can. It’s a good idea to create separate access keys for each app, environment, client, or team.
Doing this makes it easier to track usage, revoke access when needed, and apply different access key configurations.
### What happens if I lose an access key?
Access key tokens are only shown once when they are created.
If you lose one, delete the old access key, create a new one, and update your application with the new token.
### Are access keys scoped to endpoints?
No. Access keys are account-scoped and work with `https://gateway.ngrok.ai`.
You do not need to create or manage a custom endpoint URL to use the AI Gateway.
### Can I use different keys for different teams?
Yes. Create separate access keys for each team or client.
To control what each key can call, assign different [access key configurations](/docs/ai-gateway/guides/access-key-configurations). Configurations can limit providers, models, and routing credentials.
### Do I need provider keys?
It depends on the provider and how you want billing to work.
For models you can [pay for with credits](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials), you don't need to add your own provider key. That includes models from OpenAI, Anthropic, Google, DeepSeek, xAI, Moonshot AI, Z.ai, and others.
For other built-in providers, or if you want upstream usage billed to your own provider account, add a [provider key](/docs/ai-gateway/guides/attaching-provider-keys).
### Can I bring my own key for every provider?
Yes. Every built-in provider accepts your own provider key, including OpenAI and Anthropic.
ngrok-managed keys, where you pay with ngrok.ai credits instead of a provider account, are available for supported models from OpenAI, Anthropic, Google, DeepSeek, xAI, Moonshot AI, Z.ai, and others. The [model catalog](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials) shows which providers need your own key.
Add provider keys on the [Providers page](https://app.ngrok.ai/providers) in app.ngrok.ai or with the [Provider Keys API](/docs/ai-gateway/api-reference/provider-keys/create). See [Bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys).
### Are provider keys exposed to my app?
No. Your app sends an access key to the AI Gateway.
Provider keys are stored in app.ngrok.ai and used server-side when ngrok.ai calls the upstream provider. They do not need to be stored in your application code.
### Does ngrok.ai provide provider API keys?
No. ngrok.ai does not give you provider API keys to copy or use outside the gateway.
For models you can pay for with credits, ngrok.ai supplies the provider credentials. For other providers, or when you want to use your own provider account, add your own provider key.
### How do I rotate keys?
For access keys, create a new access key, update your application, then delete the old access key.
For provider keys, rotate the stored provider key value so configurations that reference the key can keep using the same key ID. See [Bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys#rotating-provider-keys).
### Can I manage the AI Gateway with an API?
Yes. The AI Gateway API at `https://api.ngrok.ai` manages access keys, access key configurations, providers, provider keys, gateway settings, credits, models, and usage.
Authenticate with an AI Gateway API key, which you create on the [Settings](https://app.ngrok.ai/settings) page.
The full [OpenAPI spec](https://api.ngrok.ai/openapi.yaml) is public, so you can generate a client in any language.
See the [AI Gateway API reference](/docs/ai-gateway/api-reference/overview).
## Credits and billing
### What do credits pay for?
Credits always pay the AI Gateway processing fee.
When you pay with credits, credits also pay the provider's model cost. If you bring your own provider key, the provider bills you for model usage and credits only pay the gateway processing fee.
### How much is the processing fee?
The ngrok.ai processing fee is `$0.05` per million tokens.
### Do credits expire?
Yes. Credits expire 365 days after purchase.
### What happens when credits run out?
The gateway rejects new requests with HTTP 402 and `ERR_NGROK_27206` until you purchase more credits from the [Billing page](https://app.ngrok.ai/billing). That's true even if you use your own provider keys, since every request pays a small processing fee from your credits.
To avoid this, turn on [automatic top-up](/docs/ai-gateway/concepts/credits#automatic-top-up) so your balance refills before it runs out.
### What's the minimum credit purchase?
The minimum credit purchase is `$5.00`.
You can purchase credits from the [Billing page](https://app.ngrok.ai/billing). Your balance can't go above `$500.00`.
### Can credits top up automatically?
Yes. Turn on automatic top-up on the [Billing page](https://app.ngrok.ai/billing). When your balance falls to an amount you choose, ngrok.ai charges your saved card and tops it back up. You can also set a maximum to spend each billing period. See [Automatic top-up](/docs/ai-gateway/concepts/credits#automatic-top-up).
### Are AI Gateway credits the same as ngrok platform billing?
No. AI Gateway credits are purchased and used in [app.ngrok.ai](https://app.ngrok.ai).
ngrok platform billing for products managed through [dashboard.ngrok.com](https://dashboard.ngrok.com) is separate, and certain features such as team members and internal endpoints for self-hosted models require a ngrok subscription.
## Models and providers
### Which providers are supported?
The AI Gateway includes built-in support for:
* OpenAI
* Anthropic
* Google
* Groq
* DeepSeek
* OpenRouter
* Hyperbolic
* InceptionLabs
* Inference.net
You can also connect self-hosted or private OpenAI-compatible and Anthropic-compatible endpoints as custom providers.
See the [Model Catalog](/docs/ai-gateway/reference/model-catalog) for the full list.
### Which providers can I call without adding a provider key?
You can see which providers require a provider key in the Model Catalog by checking the “needs provider keys” column.
Other built-in providers require you to add your own provider key before sending traffic.
### How do I choose a model?
Set the `model` field in your request.
Use a model ID when you want ngrok.ai to resolve the provider:
```json theme={null}
{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}]
}
```
Use `provider:model` when you want to choose the provider explicitly:
```json theme={null}
{
"model": "openai:gpt-4o",
"messages": [{"role": "user", "content": "Hello"}]
}
```
See [Choose a model](/docs/ai-gateway/guides/model-selection-strategies).
### How do I know which models are available?
Built-in providers and models are listed in the [Model Catalog](/docs/ai-gateway/reference/model-catalog).
The catalog includes provider IDs, model IDs, context windows, output token limits, modalities, and provider key requirements.
Custom providers declare their own models when you create them.
### Can clients use models not in the catalog?
Yes, if the request uses a provider-qualified model name and the provider allows pass-through for that model.
For example:
```json theme={null}
{
"model": "openai:gpt-5-preview",
"messages": [{"role": "user", "content": "Hello"}]
}
```
To restrict an access key to approved models only, configure a model allowlist in the [access key configuration](/docs/ai-gateway/guides/access-key-configurations).
### Can I use self-hosted models?
Yes. Create a custom provider for a model running on your machine, private network, or cloud GPU.
See [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself).
### What is a custom provider?
A custom provider is an upstream endpoint you define, such as Ollama, vLLM, LM Studio, a private deployment, or another OpenAI-compatible or Anthropic-compatible API.
Custom providers let you call models you run yourself through the same gateway URL as built-in providers.
See [Custom Providers](/docs/ai-gateway/concepts/custom-providers).
### Why isn't my custom model working?
Check that:
1. The upstream exposes a supported OpenAI or Anthropic API surface.
2. The custom provider has the correct base URL.
3. The custom provider declares the model ID you are calling.
4. The endpoint is reachable from ngrok.ai.
5. The access key configuration allows the provider and model.
6. Provider credentials are attached if the upstream requires authentication.
See [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself).
## Failover and timeouts
### How does failover work?
The gateway tries candidates in order.
It can fail over between provider keys for the same provider, then between fallback models listed in the request. The gateway does not retry the same model and provider key combination. It moves to the next available candidate.
See [Error Handling](/docs/ai-gateway/guides/error-handling).
### How do I configure fallback models?
Use `model` for the primary model and `models` for fallback models.
```json theme={null}
{
"model": "openai:gpt-4o",
"models": ["anthropic:claude-sonnet-4-6"],
"messages": [{"role": "user", "content": "Hello"}]
}
```
The gateway tries the primary model first, then each fallback model in order until one succeeds.
See [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models).
### Can I set fallbacks on the gateway instead of in each request?
Not yet. Fallback models are set per request, in the `models` list.
On the gateway side today, you can:
* Attach multiple provider keys for the same provider, so the gateway [fails over between keys](/docs/ai-gateway/guides/key-selection-failover) on rate limits, quota limits, or auth errors.
* Use [access key configurations](/docs/ai-gateway/guides/access-key-configurations) to control which providers and models each access key can reach.
To change a default model for many clients without changing their code, put the `model` and `models` values in a shared client wrapper or config your apps already read.
### Can the gateway fail over to a different provider?
Yes, if the request includes fallback models from different providers.
For example, you can try OpenAI first and fall back to Anthropic:
```json theme={null}
{
"model": "openai:gpt-4o",
"models": ["anthropic:claude-sonnet-4-6"],
"messages": [{"role": "user", "content": "Hello"}]
}
```
Each provider and model must be allowed by the access key configuration.
### How long does the gateway try before giving up?
By default, each upstream attempt can take up to 60 seconds, and the whole request, including every failover attempt, up to 120 seconds. The gateway makes at most 10 upstream attempts per request.
| Bound | Default | Configurable |
| - | - | - |
| Per-request timeout (one upstream attempt) | 60s | Yes |
| Total timeout (all attempts) | 120s | Yes |
| Upstream attempts per request | 10 | No |
Change the timeouts in [Account Settings](/docs/ai-gateway/guides/account-settings) or with the [gateway configuration API](/docs/ai-gateway/api-reference/gateway-config/update). You can also set account-wide input and output token limits there.
If the total timeout is reached, the gateway stops trying candidates and returns an error. See [Handle gateway errors](/docs/ai-gateway/guides/error-handling).
### Can I disable automatic failover?
Not directly.
To narrow failover behavior, use a single provider key per provider, send requests with a single model, avoid fallback models, and set shorter timeouts in [Account Settings](/docs/ai-gateway/guides/account-settings).
### Why am I getting rate limited even with multiple keys?
Check that multiple provider keys are attached to the relevant provider in the access key configuration.
The gateway only fails over between keys that are available to the request. See [Key selection and failover](/docs/ai-gateway/guides/key-selection-failover).
## Security and privacy
### Does ngrok.ai store request and response bodies?
The gateway processes request and response bodies in memory by default and doesn't store them unless you turn on request capture.
To turn on capture, open **Settings > Data Retention** in app.ngrok.ai and enable **Request Capture**. Capture stores the request and response headers and bodies for your request and for each attempt the gateway sends to a provider, including streamed responses. Captures are kept for 30 days and then deleted. See [Request capture](/docs/ai-gateway/guides/account-settings#request-capture).
The gateway always records request metadata for usage events and debugging, such as token counts, latencies, status codes, providers, and models.
See [Observability](/docs/ai-gateway/observability) for more details.
### How long does ngrok.ai keep my data?
| Data | Retention |
| - | - |
| Captured request and response headers and bodies (only if you turn capture on) | 30 days |
| Usage events (request metadata: tokens, latency, status, provider, model, cost) | 90 days |
### Can I see individual request and response bodies?
Yes, if you've turned on request capture. Captures are available for 30 days on the [Logs](https://app.ngrok.ai/usage) page.
Without capture, usage records include only metadata such as token counts and latency, not full request or response bodies.
See [Observability](/docs/ai-gateway/observability) for what is captured.
### Can I use the gateway for sensitive data?
Yes, but review your own security and compliance requirements.
The AI Gateway doesn't store request and response bodies unless you turn on capture. If you do, captured bodies are kept for 30 days. Requests still go to the upstream provider you call, so review the data handling terms for any provider you use.
### How do I redact PII automatically?
Automatic redaction of request and response bodies isn’t available on ngrok.ai just yet. Captures do redact credential headers, such as `Authorization`, `x-api-key`, and cookies.
Until then, redact any sensitive data in your application before sending it to the gateway.
### How do I secure my gateway when using my own provider keys?
You can store your provider keys safely in app.ngrok.ai, and have your application send only access keys.
You can use access key configurations to gently control which providers and models each key can call. If an access key is ever exposed, simply revoke it and create a new one.
See [Securing Your Gateway](/docs/ai-gateway/guides/securing-endpoints).
## Monitoring and debugging
### How do I view usage and request metrics?
You can check out the **Usage** page in app.ngrok.ai, or query usage events with the AI Gateway API.
Usage events include helpful details like request time, provider, model, token counts, latency, and status.
For more, see [Observability](/docs/ai-gateway/observability).
### How do I debug which provider was used?
Take a look at usage events in [app.ngrok.ai](https://app.ngrok.ai), or query them with the AI Gateway API to see what’s happening behind the scenes.
If you want more predictable routing while debugging, try using `provider:model` in your request, like `openai:gpt-4o`.
### Why are my requests failing silently?
Start with the response status code and error message.
Then check:
1. The access key is valid.
2. The access key configuration allows the requested provider and model.
3. The provider key is present if the provider requires one.
4. The model name is valid.
5. The account has credits.
6. The upstream provider is available.
See [Debugging](/docs/ai-gateway/guides/debugging) and [Error Codes](/docs/ai-gateway/reference/error-codes).
### Does the gateway add latency?
Yes, the gateway can add a small amount of latency for parsing, token counting, routing, and failover decisions.
Provider response time usually dominates total latency.
### How are tokens counted?
The gateway estimates token counts with `tiktoken` and uses provider-reported counts when available.
Token counts appear in [usage events](/docs/ai-gateway/observability#usage-api).
### Can I cache responses to reduce costs?
Not yet. Response caching isn’t currently available on ngrok.ai, but it’s under consideration for a future release.
## Troubleshooting
### Why am I getting "provider not allowed"?
The requested provider isn’t currently allowed by the access key configuration tied to your access key.
To fix this, you can update the configuration to allow that provider, or send the request using an access key that already has permission to call it.
See [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations) and [Error Codes](/docs/ai-gateway/reference/error-codes).
### Why am I getting "model unknown"?
The gateway could not resolve the model for the request.
Common causes include:
* The model is not in the catalog.
* The model name has a typo.
* The request uses a non-catalog model without a provider prefix.
* The access key configuration does not allow the model.
For non-catalog models, use the `provider:model` format:
```json theme={null}
{
"model": "openai:gpt-5-preview",
"messages": [{"role": "user", "content": "Hello"}]
}
```
### Why is my provider key not working?
Check that:
1. The provider key was added to the correct provider.
2. The key is valid and has not expired.
3. The provider account has access to the requested model.
4. The provider account has enough balance or quota.
5. The access key configuration routes requests through that provider key.
If usage is not appearing in your provider account, the request may be paid with credits instead of using your provider key.
### Why is failover not working?
Start by thinking about the kind of failover you want.
If you're looking for provider key failover, make sure you've attached multiple provider keys for the same provider in your access key configuration.
If you want model or provider failover, include fallback models in your request:
```json theme={null}
{
"model": "openai:gpt-4o",
"models": ["anthropic:claude-sonnet-4-6"],
"messages": [{"role": "user", "content": "Hello"}]
}
```
Every fallback provider and model must be allowed by the access key configuration.
### Why is the gateway timing out?
The total request time may be hitting the timeout set in [Account Settings](/docs/ai-gateway/guides/account-settings).
Try increasing the total timeout, checking upstream provider latency, or reducing the number of fallback candidates.
### Why was my request rejected before reaching a provider?
The gateway can reject a request before upstream routing when:
* The access key is missing or invalid.
* The access key configuration does not allow the provider or model.
* The model cannot be resolved.
* The account has insufficient credits.
* Required provider credentials are missing.
Check the response error code and see [Error Codes](/docs/ai-gateway/reference/error-codes).
## Routing behavior
### Can I route based on request content?
Not at the gateway layer today.
For now, you can use separate access keys and configurations for each client, or handle routing in your application before sending requests to the gateway.
### How do I prioritize certain models or providers?
List fallback models in preference order in the request body.
```json theme={null}
{
"model": "openai:gpt-4o",
"models": ["anthropic:claude-sonnet-4-6"],
"messages": [{"role": "user", "content": "Hello"}]
}
```
For different clients or teams, create separate access keys with different configurations.
### Does the gateway support streaming?
Yes. Streaming is supported, and the gateway forwards SSE streams transparently.
### What happens if a stream fails partway through?
A stream that fails partway through is billed, because its first bytes were already delivered to your client. If the provider doesn't report usage for that request, the gateway estimates token counts, and the usage event is marked `usageEstimated: true`.
To see what happened, look up the request by its `Ngrok-AIG-Request-Id` with the [request attempts endpoint](/docs/ai-gateway/api-reference/usage/request-attempts). See [Handle gateway errors](/docs/ai-gateway/guides/error-handling).
## See also
* [Quickstart](/docs/ai-gateway/quickstart): Get started quickly
* [How It Works](/docs/ai-gateway/how-it-works): Request flow and failover
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Model IDs and provider-qualified routing
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Ordered model fallback
* [Bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys): Store upstream credentials
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations): Scope access and configure routing
* [Error Codes](/docs/ai-gateway/reference/error-codes): Understand failures
# Set up an access key configuration
Source: https://ngrok.com/docs/ai-gateway/guides/access-key-configurations
Scope providers and models and attach provider credentials to an access key.
Every request to `https://gateway.ngrok.ai` must include an [access key](/docs/ai-gateway/concepts/access-keys). Upstream provider credentials are managed in [app.ngrok.ai](https://app.ngrok.ai) and injected server-side based on the access key's **configuration**—see [Access keys vs provider keys](/docs/ai-gateway/concepts/access-keys#access-keys-vs-provider-keys).
Access key configurations control:
* **Access scope**: which providers and models the key may call
* **Routing rules**: whether to pay with credits or use your stored [provider keys](/docs/ai-gateway/guides/attaching-provider-keys) for each provider
See [Create a configuration](#create-a-configuration) below, or the [Access Key Configurations API](/docs/ai-gateway/api-reference/access-key-configurations/create).
## How it fits together
```mermaid theme={null}
flowchart LR
App["Your app"] -->|"access key only"| Gateway["gateway.ngrok.ai"]
Gateway --> Config["Access key configuration"]
Config --> Ngrok["Pay with credits"]
Config --> BYOK["Stored provider keys"]
Ngrok --> OpenAI["OpenAI / Anthropic"]
BYOK --> Providers["Other built-in or custom providers"]
```
1. Your app sends an **access key** with each request.
2. The gateway loads the configuration linked to that key (or default rules if none is linked).
3. The AI Gateway selects upstream credentials from the configuration's routing rules.
## Default behavior
An access key with **no configuration** (allow-all scope) can reach any provider and model your account supports. For built-in models you [can pay for with credits](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials), an ngrok.ai key is used automatically when you have [credits](/docs/ai-gateway/concepts/credits).
To use your own provider accounts, restrict scope, or control failover, create a configuration and assign it to the key.
## Create a configuration
### Via the ngrok dashboard
1. Open [app.ngrok.ai](https://app.ngrok.ai) → **Keys** → **Configurations**.
2. Click **New configuration**.
3. Set a name and optional description.
4. Under **Access**, allow only the providers and models this key should use.
5. Under **Routing**, add a rule per provider:
* **ngrok**: pay with credits. ngrok.ai supplies the credentials ([supported providers](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials) only)
* **Bring your own API key**: attach one or more stored provider keys (tried in order)
6. Save the configuration.
7. On **Keys**, edit an access key and assign the configuration.
### Via the AI Gateway API
Create configurations with the [Access Key Configurations API](/docs/ai-gateway/api-reference/access-key-configurations/create). Authorize the request with your [AI Gateway API key](/docs/ai-gateway/concepts/access-keys#credentials-overview).
```bash theme={null}
curl -X POST https://api.ngrok.ai/access-key-configurations \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Production OpenAI BYOK",
"access": {
"providers": { "allow": ["openai"] },
"models": { "allow": ["openai/gpt-4o"] }
},
"router": {
"rules": [
{
"provider": "openai",
"steps": [
{
"type": "user",
"keySelectionStrategy": "ordered",
"keys": [{ "id": "aigpk_xxxxx" }]
}
]
}
]
}
}'
```
Link the configuration when creating or updating an access key:
```bash theme={null}
curl -X PATCH https://api.ngrok.ai/access-keys/aigk_xxxxx \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "accessKeyConfigurationId": "aigac_xxxxx" }'
```
See the [Access Key Configurations API reference](/docs/ai-gateway/api-reference/access-key-configurations/create) and [Access Keys API](/docs/ai-gateway/api-reference/access-keys/update).
## Routing rules
Each routing rule targets exactly one **provider** or one **model** and defines an ordered list of steps. A model rule uses the provider-qualified form, such as `openai:openai/gpt-5.5`, and takes precedence over a provider rule for the same provider. A configuration can have at most one rule per provider.
| Step type | Meaning |
| - | - |
| `ngrok` | Pay with credits. ngrok.ai supplies the key ([supported providers](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials) only) |
| `user` | Use attached provider keys, tried in list order |
For built-in providers, you can pay with credits, bring your own key, or list your own keys first with an `ngrok` step after them as a fallback. The gateway uses the first step that has usable credentials. The `ngrok` fallback only runs when your keys hit auth errors or rate limits.
When a configuration has no rule for a provider, requests to that provider are paid with credits only. Stored provider keys are not used without a rule.
Custom providers require a `user` step with at least one provider key when the upstream requires authentication.
## Multi-key failover
Attach multiple provider keys to the same routing rule step. The gateway tries them in order when a key hits a rate limit or auth error. Server errors and timeouts move to the next model instead. See [Multi-key failover](/docs/ai-gateway/guides/key-selection-failover).
## Restrict providers and models
Use the **access** block to limit what an access key can call:
```json theme={null}
{
"access": {
"providers": { "allow": ["openai", "anthropic"] },
"models": { "allow": ["openai/gpt-4o", "anthropic/claude-sonnet-4-6"] }
}
}
```
Omit `access` entirely for allow-all scope. An empty `allow` array blocks all traffic on that dimension.
## Next steps
* [Access Keys](/docs/ai-gateway/concepts/access-keys): Create keys and assign configurations
* [Bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys): Store upstream credentials
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Limit what a key can call
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Choose models in requests
* [Securing Your Gateway](/docs/ai-gateway/guides/securing-endpoints): Per-client keys and revocation
# Configure account settings
Source: https://ngrok.com/docs/ai-gateway/guides/account-settings
Configure account-wide AI Gateway timeouts and token limits.
Account-wide gateway settings apply to every request through `https://gateway.ngrok.ai`, so you can set defaults like timeouts and token limits once instead of repeating them on every [access key configuration](/docs/ai-gateway/guides/access-key-configurations).
## Timeouts
| Setting | Default | Description |
| - | - | - |
| `perRequestTimeout` | `60s` | Max time for a single upstream attempt |
| `totalTimeout` | `120s` | Max time for a request including all failover attempts |
If a single attempt exceeds `perRequestTimeout`, the gateway moves on to the next fallback. If total time exceeds `totalTimeout`, the gateway returns an error. `perRequestTimeout` must be less than or equal to `totalTimeout`.
### Streaming responses
Streams use the timeouts differently, so a long completion isn't cut off:
* The per-request timeout applies only until the provider sends the first byte. After that, the stream fails if the provider sends nothing for 30 seconds.
* The default total timeout applies only until the first byte. After that, the stream can run for up to 15 minutes.
* A `totalTimeout` you set yourself applies to the whole stream, including the time after the first byte.
If you set `totalTimeout`, long streaming responses stop when it expires. Leave it unset to keep the 15-minute limit for streams.
## Token limits
| Setting | Default | Description |
| - | - | - |
| `maxInputTokens` | none | Reject requests above estimated input tokens |
| `maxOutputTokens` | none | Cap completion length |
Leave token limits unset for no cap. Set them to block oversized requests before they reach a provider. Limits must be greater than zero.
`maxOutputTokens` also applies when your request doesn't set an output limit: the gateway adds one. When your request asks for more, the gateway lowers it to your limit, and to the model's own maximum.
## Request capture
Request capture stores the request and response headers and bodies, including prompts and completions, for your request and each attempt the gateway sends to a provider. You can inspect them on the [Logs](https://app.ngrok.ai/usage) page. Capture is off by default.
To turn it on, open **Settings > Data Retention** in app.ngrok.ai and set **Request Capture** to enabled. Captures are kept for 30 days. Credential headers such as `Authorization` and `x-api-key` are redacted. Bodies are stored as sent.
## Via dashboard
1. Open [Settings](https://app.ngrok.ai/settings) in app.ngrok.ai
2. On **General**, edit **Total timeout**, **Per-request timeout**, and optional token limits
3. Save
**General** also shows the gateway URL (`https://gateway.ngrok.ai`). The other Settings pages are **Data Retention** for [request capture](#request-capture), **Admin API Keys** for [AI Gateway API keys](/docs/ai-gateway/concepts/access-keys#credentials-overview), and **Account**, which links to [dashboard.ngrok.com](https://dashboard.ngrok.com) for your account details and team members.
## Via the AI Gateway API
Get current settings:
```bash theme={null}
curl https://api.ngrok.ai/gateway-config \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY"
```
Update settings (omitted fields keep their current values):
```bash theme={null}
curl -X PATCH https://api.ngrok.ai/gateway-config \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"perRequestTimeout": "60s",
"maxInputTokens": 128000,
"maxOutputTokens": 8192
}'
```
Clear a token limit by sending `null`:
```bash theme={null}
curl -X PATCH https://api.ngrok.ai/gateway-config \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "maxInputTokens": null }'
```
Duration fields use Go duration strings (for example, `30s`, `2m`).
See the [Gateway configuration API reference](/docs/ai-gateway/api-reference/gateway-config/get).
## Next steps
* [How It Works](/docs/ai-gateway/how-it-works): Request flow and failover
* [Choose how to reach providers](/docs/ai-gateway/guides/configuring-providers): Credits, provider keys, and self-run models
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations): Per-key scope and routing
# Bring your own provider key
Source: https://ngrok.com/docs/ai-gateway/guides/attaching-provider-keys
Add an upstream provider key and use it through the AI Gateway.
Use provider keys to let ngrok.ai call an upstream provider with your own credentials.
Provider keys are the API keys you already use with OpenAI, Google, Anthropic, and others. You can add them to ngrok.ai once, and it uses them to call those providers on your behalf, keeping keys out of your app.
For [certain providers](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials), like OpenAI, Anthropic, Google, and DeepSeek, you can skip provider keys and [pay with credits](/docs/ai-gateway/guides/pay-with-credits) instead.
## Add a provider key
### Via the ngrok dashboard
Head over to the [Providers](https://app.ngrok.ai/providers) page and choose the provider you want from either the **Built-in** or **Custom** tab.
Once you're on the provider's page, scroll down to **API keys** and add your key there.
### Via the AI Gateway API
You can add your own API Keys for providers via the [Provider Keys API](/docs/ai-gateway/api-reference/provider-keys/create):
```bash theme={null}
curl -X POST https://api.ngrok.ai/provider-keys \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"providerId": "openai",
"name": "My OpenAI Key",
"value": "sk-proj-..."
}'
```
After you add a key, the dashboard only shows a redacted version (`first10***last4`). Make sure you keep a copy of the full key from your provider, since you won’t be able to see it again here. Provider keys are shared across your account, so you can use the same key with multiple access keys.
When a key does not have an access configuration attached, the gateway begins using this provider key immediately. To select specific keys, define failover order, or restrict providers and models, use an access key configuration.
## Control access with a configuration
An access key without a configuration uses any provider keys you've added, so it works out of the box.
If you need more control, you can attach an [access key configuration](/docs/ai-gateway/guides/access-key-configurations). This lets you choose which key to use, set a fallback order, or limit which providers and models are available.
First, make sure you've already [added a key](#add-a-provider-key) for the provider.
Next, go to your [access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration). Then add a routing rule for the provider, choose **Bring your own API key**, and pick the key you added in the previous step.
You can add more than one key for the same provider—if one fails or hits a limit, the gateway will automatically try the next one in your list. For more details, see [key selection and failover](/docs/ai-gateway/guides/key-selection-failover).
When using the ngrok.ai API, reference the key's ID in the configuration's router rules:
```json theme={null}
{
"router": {
"rules": [
{
"provider": "openai",
"steps": [
{
"type": "user",
"keySelectionStrategy": "ordered",
"keys": [{ "id": "aigpk_xxxxx" }]
}
]
}
]
}
}
```
Navigate to the [Access Keys](https://app.ngrok.ai/keys) page, and assign the configuration to the [access key](/docs/ai-gateway/concepts/access-keys) your app uses.
Your app only needs to send the access key. The gateway uses it to find the right configuration, chooses the provider key, and makes the request for you:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Access key, not the provider key
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
```
## Rotating provider keys
[Rotating provider keys](/docs/ai-gateway/api-reference/provider-keys/rotate) lets you update its value without changing its ID, so anything already using it keeps working. This means you can keep your existing configurations as they are.
Update the key by sending its new value to the [Provider Keys API](/docs/ai-gateway/api-reference/provider-keys/rotate), using your [ngrok.ai API key](/docs/ai-gateway/concepts/access-keys#credentials-overview):
```bash theme={null}
curl -X POST https://api.ngrok.ai/provider-keys/aigpk_xxxxx/rotate \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "My OpenAI Key",
"value": "sk-proj-..."
}'
```
Send a test request with your access key. The key ID is unchanged, so there's nothing else to update.
## Common issues
| Problem | What to check |
| - | - |
| Request is rejected before routing | The access key configuration may not allow the provider or model |
| Provider returns an auth error | The provider key may be missing, invalid, expired, or unable to call the requested model |
| Usage is not appearing in provider billing | The request may be paid with credits instead of using your provider key |
## Next steps
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations): Attach keys and set scope
* [Bring Your Own Keys](/docs/ai-gateway/concepts/bring-your-own-keys): Built-in vs custom providers
* [Key selection and failover](/docs/ai-gateway/guides/key-selection-failover): Ordered key failover
# Automatic model selection
Source: https://ngrok.com/docs/ai-gateway/guides/automatic-model-selection
Let ngrok.ai pick a model for each request with ngrok/auto.
Set the model to `ngrok/auto` when you want ngrok.ai to choose the model for each request.
ngrok.ai reads the prompt, estimates how capable a model it needs, and tries the models your access key can reach in that order, starting with the cheapest model that fits.
Use it when your traffic mixes simple and hard prompts and you'd rather not pay top-model prices for "hello" or a unit conversion.
## Send a request
Set `model` to `ngrok/auto`:
```python Python highlight={9} theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx", # Your access key
)
response = client.chat.completions.create(
model="ngrok/auto",
messages=[{"role": "user", "content": "Explain the difference between TCP and UDP."}],
)
print(response.choices[0].message.content)
```
```bash curl theme={null}
curl https://gateway.ngrok.ai/v1/chat/completions \
-H "Authorization: Bearer ng-xxxxx-g1-xxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "ngrok/auto",
"messages": [{"role": "user", "content": "Explain the difference between TCP and UDP."}]
}'
```
On Chat Completions (`/v1/chat/completions`), Responses (`/v1/responses`), and Messages (`/v1/messages`), leaving out `model` entirely has the same effect.
Most SDKs require a model, so `ngrok/auto` is the clearer choice.
`ngrok/auto` also works on these endpoints:
| Endpoint | How to ask for `ngrok/auto` |
| - | - |
| Gemini `generateContent` | Put it in the path: `/v1beta/models/ngrok/auto:generateContent` |
| Gemini Interactions (`/v1beta/interactions`) | `"model": "ngrok/auto"` in the body |
| OpenAI Decisions (`/v1/decisions`) | `"model": "ngrok/auto"`. Only `gpt-6-luna` serves Decisions, so this always picks it. See [Typed-question APIs](/docs/ai-gateway/guides/decisions-and-system-one) |
## How ngrok.ai picks the model
ngrok.ai sorts models into three price bands by what they charge per million input tokens:
| Band | Input price |
| - | - |
| Low | Under \$1 per million tokens |
| Medium | \$1 to under \$5 per million tokens |
| High | \$5 or more per million tokens |
On Chat Completions and Messages, ngrok.ai first asks a small classifier model how much capability the prompt needs:
* **Simple prompts**, like greetings, common facts, short rewrites, or a regex, go to the low band.
* **Ordinary professional work**, like writing or fixing a small program, a SQL query, or summarizing a document, goes to the medium band. If that work needs little step-by-step reasoning, it goes to the high band instead, because the answer depends more on writing quality.
* **Hard prompts**, like multi-step reasoning, competition-style math, rigorous proofs, or expert analysis, go to the high band.
If the classifier can't answer quickly, the request starts at the low band instead of failing.
On the other endpoints, ngrok.ai doesn't classify the prompt, so every request starts at the low band.
### The order models are tried in
Once ngrok.ai has a band, it orders every model your access key can use:
1. Models from [custom providers](/docs/ai-gateway/concepts/custom-providers) you've added a provider key for.
2. The models that do best on that kind of prompt.
3. The rest of the band, cheapest first.
4. The bands above, cheapest first.
5. The bands below, cheapest first.
6. Models with no published price.
The band sets where the list starts, not which models are allowed. If the first model fails, the gateway [fails over](/docs/ai-gateway/guides/error-handling) down the list the same way it does for any other request.
### Reasoning effort
On Chat Completions and Messages, the classifier also picks a reasoning effort: low, medium, or high.
For each model that has a reasoning setting the gateway can set, such as `reasoning_effort` or Anthropic's adaptive thinking effort, that level replaces any reasoning setting you sent.
Models without one get your request unchanged.
If the classifier can't decide, your own reasoning settings apply.
## See which model answered
Read the `Ngrok-AIG-Model` [response header](/docs/ai-gateway/how-it-works#response-headers).
It names the model that produced the response.
The `model` field in the response body comes from the provider, so use the header when you need to know what answered.
The models ngrok.ai prefers can change as new models launch and prices move, so don't depend on a particular model being picked.
## Access key configurations still apply
`ngrok/auto` only picks from models the access key can already reach:
* The [access key configuration](/docs/ai-gateway/guides/access-key-configurations) must allow the provider and model.
* The model needs usable credentials: you [pay with credits](/docs/ai-gateway/guides/pay-with-credits) or have [your own provider key](/docs/ai-gateway/guides/attaching-provider-keys) routed to it.
* The model must support the endpoint you called.
* The model catalog must mark the model as available to `ngrok/auto`. Narrow-purpose models, such as translation or classifier models, and models past their deprecation date are left out.
To keep `ngrok/auto` inside a set of providers or models, [restrict the access key](/docs/ai-gateway/guides/restrict-providers-and-models).
If none of the models the key can reach qualify, the request fails with [`ERR_NGROK_27227`](/docs/ai-gateway/reference/error-codes#err_ngrok_27227). Name a model in the request instead.
## Combining with fallback models
`ngrok/auto` and a [`models` fallback list](/docs/ai-gateway/guides/configure-fallback-models) are two different ways to pick models, so don't use them together:
* On Chat Completions and Messages, if you list real models alongside `ngrok/auto`, the gateway ignores `ngrok/auto` and uses your list as an ordinary fallback list.
* On the Gemini endpoints, combining them returns `ERR_NGROK_27228` with the message `Invalid request: models cannot be combined with ngrok/auto`.
## Billing
You pay for the model that served the response, the same as if you'd named it.
The classifier isn't billed as model usage. Its input tokens count toward the [processing fee](/docs/ai-gateway/concepts/credits#processing-fee) on that request, whether you pay with credits or use your own provider keys.
Requests on endpoints that skip the classifier add nothing extra.
## Next steps
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Pick a model yourself by ID or provider
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Control the failover order yourself
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Limit what `ngrok/auto` can pick
# Configure fallback models
Source: https://ngrok.com/docs/ai-gateway/guides/configure-fallback-models
Try another model if the primary model request fails.
Use fallback models when you want the AI Gateway to try another model if the primary request fails.
Fallback is useful when you want better availability across providers, or when you want to try a private model first and use a hosted model as a backup.
## Add fallback models
Set the primary model with `model`. Set fallback models with `models`.
```json theme={null}
{
"model": "gpt-4o",
"models": ["gpt-4o-mini", "anthropic:claude-sonnet-4-6"],
"messages": [{"role": "user", "content": "Hello"}]
}
```
The gateway tries `gpt-4o` first. If that request fails with a rate limit, an auth error, a server error, or a timeout, it tries each entry in `models` in order until one succeeds. Other 4xx errors, such as an invalid request, return right away. See [what triggers failover](/docs/ai-gateway/guides/error-handling).
## Choose the provider for each fallback
Fallback models can use model IDs or `provider:model`.
```json theme={null}
{
"model": "openai:gpt-4o",
"models": [
"openai:gpt-4o-mini",
"anthropic:claude-sonnet-4-6"
],
"messages": [{"role": "user", "content": "Hello"}]
}
```
Use provider-qualified model names when you want to control exactly which provider each fallback uses.
## Fall back from a private model to a hosted model
Fallback works with [custom providers](/docs/ai-gateway/concepts/custom-providers), too.
```json theme={null}
{
"model": "my-ollama:llama3.2",
"models": ["openai:gpt-4o-mini"],
"messages": [{"role": "user", "content": "Hello"}]
}
```
In this example, the gateway tries your `my-ollama` provider first. If that request fails, it falls back to OpenAI.
## Choose fallback models carefully
Pick fallback models that can handle the same kind of request as the primary model. Check each model for:
* Input modality.
* Tool calling support.
* Output size.
* Context window.
* Latency expectations.
* Provider credentials.
Use the [model catalog](/docs/ai-gateway/reference/model-catalog) to compare built-in model capabilities.
## Access restrictions still apply
Fallback models must be allowed by the [access key configuration](/docs/ai-gateway/guides/access-key-configurations) assigned to the access key.
If a fallback model isn't allowed, the gateway skips it and names it in the `Ngrok-AIG-Rejected-Models` response header. The request still runs with the models that are allowed. It fails only when none of the models you listed are allowed.
## Next steps
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Choose a model by ID or provider
* [Automatic model selection](/docs/ai-gateway/guides/automatic-model-selection): Let ngrok.ai pick the model instead. Don't combine it with `models`
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Limit what an access key can call
* [Model catalog](/docs/ai-gateway/reference/model-catalog): Compare model capabilities
# Choose how to reach providers
Source: https://ngrok.com/docs/ai-gateway/guides/configuring-providers
Decide whether to use credits, bring your own provider key, or connect a model you run yourself.
The AI Gateway can reach providers in three ways. Pick the path that matches what you're trying to do.
## Use a provider without a provider account
Use [credits](/docs/ai-gateway/concepts/credits) when you want the fastest path to OpenAI, Anthropic, Google, DeepSeek, or another [provider you can pay for with credits](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials). The gateway supplies upstream credentials and bills model usage through your credit balance.
Start here: [Pay with credits](/docs/ai-gateway/guides/pay-with-credits).
## Bring your own provider key
Bring your own key when you want model usage billed to your provider account, need a provider that requires your own credentials, or want to use your own provider account.
Start here: [Bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys).
## Use a model you run yourself
Use a custom provider when your model runs on your machine, private network, cloud GPU, or another OpenAI- or Anthropic-compatible endpoint outside the built-in catalog.
Start here: [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself).
## Make the provider usable from a request
Adding a provider or provider key doesn't route traffic by itself. A working request needs:
1. A provider: built-in or custom.
2. A credential source: credits or a provider key, when required.
3. An [access key configuration](/docs/ai-gateway/guides/access-key-configurations) that allows the provider and model.
4. An [access key](/docs/ai-gateway/concepts/access-keys) assigned to that configuration.
5. A request with a matching `model` or `provider:model`.
If requests are rejected before they reach the provider, check [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models).
## Next steps
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Use model IDs in requests
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations): Scope access and choose credentials
* [Model catalog](/docs/ai-gateway/reference/model-catalog): Check providers, models, and key requirements
# Debug failed requests
Source: https://ngrok.com/docs/ai-gateway/guides/debugging
Diagnose AI Gateway request failures on gateway.ngrok.ai.
When troubleshooting a request to `https://gateway.ngrok.ai`:
1. Record the `Ngrok-AIG-Request-Id` [response header](/docs/ai-gateway/how-it-works#response-headers). Every response carries it, errors included, and it identifies the request in usage data.
2. Check the error code and message in the response body. See [Error Codes](/docs/ai-gateway/reference/error-codes).
3. Read `Ngrok-AIG-Attempts` to see whether failover ran. A count above 1 means the gateway tried more than one upstream candidate before it gave up, so the cause is upstream rather than in your request. An absent header means the request failed before any attempt, which points at the request body or the access key configuration.
4. Verify your app sends an [access key](/docs/ai-gateway/concepts/access-keys)—not an upstream provider key.
5. Confirm the access key's [configuration](/docs/ai-gateway/guides/access-key-configurations) allows the provider and model you requested, with routing credentials attached.
6. Look the request up in the dashboard at [app.ngrok.ai](https://app.ngrok.ai), or query it with the [Usage API](/docs/ai-gateway/observability#usage-api).
Common fixes:
| Symptom | Check |
| - | - |
| 401 Unauthorized | Access key missing, malformed, or deleted |
| 402 Payment Required (27206) | Out of credits: [purchase credits](/docs/ai-gateway/concepts/credits). This happens even if you use your own provider keys |
| No keys available for provider (27202) | Configuration missing a routing rule or provider keys for the requested provider |
| Provider or model not allowed by the access policy (27231, 27232) | Model or provider blocked by the configuration's access scope |
| Every model failed | The response carries the last model's error. Read `Ngrok-AIG-Attempts` and the attempt chain. See [Handle gateway errors](/docs/ai-gateway/guides/error-handling) |
| Response names a model you did not expect | Read `Ngrok-AIG-Model`, not the `model` field in the body. The body is passed through byte-for-byte and keeps the provider's own wording |
See [Handle gateway errors](/docs/ai-gateway/guides/error-handling) for retry and failover behavior.
# Typed-question APIs
Source: https://ngrok.com/docs/ai-gateway/guides/decisions-and-system-one
Call OpenAI Decisions and Typesafe AI System One through ngrok.ai.
Some models don't chat. You send them some input and a list of typed questions, and they send back a typed answer to each one, such as true or false, one choice from a list, or a score.
That's useful for routing support tickets, flagging content, or scoring urgency without parsing free-form text.
ngrok.ai serves two of these APIs:
| API | Endpoint | Provider | Models |
| - | - | - | - |
| [OpenAI Decisions](https://developers.openai.com/api/docs/guides/decisions) | `POST /v1/decisions` | OpenAI | `gpt-6-luna` |
| [Typesafe AI System One](https://docs.typesafe.ai) | `POST /v1/systemone` | [Typesafe AI](/docs/ai-gateway/providers/typesafeai) | `jev-latest`, `jev-preview`, `jev-1.13.0` |
You can [pay with credits](/docs/ai-gateway/guides/pay-with-credits) for both, or [bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys) for OpenAI or Typesafe AI.
## Decisions requests
A Decisions request has an `input`, in the same message format as the Responses API, and an array of `questions`.
Each question has a `type` (`predicate`, `choice`, or `score`), a `name`, and `instructions`.
```bash theme={null}
curl https://gateway.ngrok.ai/v1/decisions \
-H "Authorization: Bearer ng-xxxxx-g1-xxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-luna",
"input": [
{
"role": "user",
"content": [
{"type": "input_text", "text": "I was charged twice for my March invoice and need one charge refunded today."}
]
}
],
"questions": [
{"type": "predicate", "name": "is_refund_request", "instructions": "Does the customer ask for a refund?"},
{
"type": "choice",
"name": "team",
"instructions": "Which team owns this ticket?",
"choices": [
{"value": "billing", "description": "Charges, invoices, and refunds."},
{"value": "technical", "description": "Product defects and outages."}
]
}
]
}'
```
The response has an `answers` array with one entry per question. A `predicate` answer has the `probability` that it's true. A `choice` answer names the `choice` it picked, with a probability for each option:
```json theme={null}
{
"model": "gpt-6-luna",
"answers": [
{"type": "predicate", "name": "is_refund_request", "probability": 1.0},
{
"type": "choice",
"name": "team",
"choice": "billing",
"probabilities": [
{"value": "billing", "probability": 1.0},
{"value": "technical", "probability": 0.0}
],
"confidence": 1.0
}
],
"usage": {"input_tokens": 286, "output_tokens": 0, "total_tokens": 286}
}
```
The gateway forwards `model`, `input`, `questions`, and `safety_identifier`. It removes any other top-level field and names it in the `Ngrok-AIG-Removed-Params` [response header](/docs/ai-gateway/how-it-works#response-headers).
See [OpenAI's Decisions guide](https://developers.openai.com/api/docs/guides/decisions) for every question type and option.
`"model": "ngrok/auto"` also works and always picks `gpt-6-luna`. Any other model returns [`ERR_NGROK_27226`](/docs/ai-gateway/reference/error-codes#err_ngrok_27226), because no other model serves Decisions.
When you pay with credits, OpenAI bills a decision on input tokens only, at `gpt-6-luna`'s input rate.
## Typesafe AI requests
A System One request has a `state`, the text to evaluate, and a `questions` object that maps each question ID to a typed question.
```bash theme={null}
curl https://gateway.ngrok.ai/v1/systemone \
-H "Authorization: Bearer ng-xxxxx-g1-xxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "jev-latest",
"state": "The server returned 500 for every request for ten minutes.",
"questions": {
"is_urgent": {
"type": "noul",
"instructions": "Is this an urgent production incident?"
}
}
}'
```
The response maps each question ID to its answer, with a calibrated probability:
```json theme={null}
{
"model": "jev-1.13.0",
"answers": {"is_urgent": {"type": "noul", "noul": 0.91}},
"usage": {"input_tokens": 287, "output_tokens": 23}
}
```
The gateway forwards `model`, `state`, and `questions`, and removes any other top-level field.
See the [Typesafe AI API reference](https://docs.typesafe.ai) for question types such as `choice` and `score`, and the [Typesafe AI provider page](/docs/ai-gateway/providers/typesafeai) for setup.
Name a Jev model in the request. `ngrok/auto` doesn't pick Jev models, so it returns [`ERR_NGROK_27227`](/docs/ai-gateway/reference/error-codes#err_ngrok_27227) on this endpoint.
## What's different from chat requests
Both APIs differ from Chat Completions and Messages in a few ways:
* **No streaming**: A request with `"stream": true` returns `ERR_NGROK_27228` before reaching the provider.
* **No fallback list**: The gateway reads only `model`. Each API has a single provider, so a `models` list is removed rather than used.
* **POST only**: Each API has a single create endpoint. Other methods and paths below it return an error.
* **Same billing model**: Every request pays the [processing fee](/docs/ai-gateway/concepts/credits#processing-fee). When you pay with credits, credits also cover the model cost.
## Next steps
* [Typesafe AI](/docs/ai-gateway/providers/typesafeai): Set up Typesafe AI with credits or your own key
* [OpenAI](/docs/ai-gateway/providers/openai): Set up OpenAI with credits or your own key
* [How it works](/docs/ai-gateway/how-it-works#response-headers): Read the gateway's response headers
# Handle gateway errors
Source: https://ngrok.com/docs/ai-gateway/guides/error-handling
Understand which failures the AI Gateway retries, the order it tries candidates in, and how timeouts bound the whole request.
When an upstream attempt fails, the AI Gateway either moves to another candidate or stops and returns the error.
This page explains which failures it retries, in what order, and what bounds the retrying.
## What triggers failover
The gateway moves to another candidate on these failures:
* Authentication failures: HTTP 401 or 403 because the provider rejected the key. A 401 or 403 for any other reason stops the request.
* Rate limits: HTTP 429.
* Server errors: HTTP 500 and above.
* Request timeouts: HTTP 408, or the attempt exceeding your per-request timeout.
* Network failures: connection errors, DNS failures, and TLS errors.
Any other 4xx response stops the request immediately.
A malformed request or an unsupported parameter is not going to succeed on a different provider, so the gateway returns the error rather than spending your quota on it.
## Failover order
Where the gateway goes next depends on how the attempt failed.
| Failure | Order the gateway tries |
| - | - |
| 401 or 403 | Next provider key for the same provider, then an ngrok-managed key if one is available, then the next model |
| 429 | A different quota pool for the credential, then an ngrok-managed key if one is available, then the next model |
| 500 and above, 408, or a network failure | The next model |
Model candidates come from the `model` field first, then the `models` array in order:
```json theme={null}
{
"model": "gpt-4o",
"models": ["anthropic:claude-sonnet-4-5", "google:gemini-3.6-flash"],
"messages": [{"role": "user", "content": "Hello"}]
}
```
The gateway never retries the same model and key combination, except in the one case below.
A bare model ID, such as `gpt-4o`, also expands to every provider that serves that model. The model author's own provider goes first, then resellers such as OpenRouter. A `provider:model` ID, such as `openai:gpt-4o`, reaches only that provider.
To fail over to a different model, list it in the `models` array, or set it up as a [fallback model](/docs/ai-gateway/guides/configure-fallback-models).
### Retrying the same provider
When a provider answers 429 or 503 with a `Retry-After` header, the gateway waits and retries the same backend instead of moving on.
It does that only when the wait is 5 seconds or less, only when the wait still fits inside your total timeout, and at most twice per request.
Otherwise it treats the response as a rate limit or a server error and moves to the next candidate.
## What bounds the retrying
Two timeouts and an attempt cap bound every request:
| Bound | Default | What it limits |
| - | - | - |
| Per-request timeout | 60s | A single upstream attempt |
| Total timeout | 120s | The whole request, including every attempt and any `Retry-After` wait |
| Attempt cap | 10 | Upstream attempts per client request. Not configurable |
Streams work differently after the first byte. See [Streaming responses](/docs/ai-gateway/guides/account-settings#streaming-responses).
Set the timeouts for your account in [Account Settings](/docs/ai-gateway/guides/account-settings), or through the [Configuration API](/docs/ai-gateway/api-reference/gateway-config/get).
When the total timeout is reached, failover stops even if candidates remain, and the gateway returns `ERR_NGROK_3810`.
## Failures that never reach failover
Some requests fail before the gateway makes any upstream attempt.
These return immediately, and the response carries no `Ngrok-AIG-Attempts` header:
* The request body could not be parsed.
* The model is unknown, or the model address is malformed.
* The requested provider or model is blocked by the access key configuration's access scope.
* No provider key is available for the requested provider.
* The account has no credits. This happens even if you use your own provider keys.
None of these are billed.
The gateway bills an attempt only once its response reaches your client, so a request that never reached a provider costs nothing.
A stream that fails partway through is billed, because its first bytes were already delivered.
See [Error Codes](/docs/ai-gateway/reference/error-codes) for the code each of these returns.
## Best practices
1. **Attach several provider keys** per provider so an exhausted credential fails over instead of failing the request. See [Multi-key failover](/docs/ai-gateway/guides/key-selection-failover).
2. **List candidates from more than one provider** so a provider-wide outage has somewhere to go.
3. **Set timeouts to match your latency budget.** A total timeout that is too tight cuts failover short; one that is too loose makes a slow failure look like a hang.
4. **Record `Ngrok-AIG-Request-Id` from every response** so you can look a failure up afterwards. See [Debug failed requests](/docs/ai-gateway/guides/debugging).
## Next steps
Error codes, causes, and solutions
Diagnose a failure from the response
# Upload and use files
Source: https://ngrok.com/docs/ai-gateway/guides/files
Upload files to OpenAI or Anthropic through ngrok.ai and reference them in requests.
Use the Files API when you want to upload a document or image once and reference it by ID in later requests, instead of sending the bytes inline every time.
The AI Gateway serves the OpenAI and Anthropic Files APIs at `https://gateway.ngrok.ai/v1/files`.
The request and response shapes match the provider's own API, so the OpenAI and Anthropic SDKs work with one extra header.
## Endpoints
| Method | Path | Description |
| - | - | - |
| `POST` | `/v1/files` | Upload a file. The body is `multipart/form-data`. |
| `GET` | `/v1/files` | List files. |
| `GET` | `/v1/files/{file_id}` | Get a file's metadata. |
| `GET` | `/v1/files/{file_id}/content` | Download a file's contents. |
| `DELETE` | `/v1/files/{file_id}` | Delete a file. |
## Name the provider
A file request has no model, so the gateway can't work out the provider on its own.
Every Files API request must send the `Ngrok-AIG-Provider` header:
| Provider | Header value |
| - | - |
| OpenAI | `Ngrok-AIG-Provider: openai` |
| Anthropic | `Ngrok-AIG-Provider: anthropic` |
The gateway removes this header before it calls the provider.
Other providers, including Google, aren't supported.
The access key's [configuration](/docs/ai-gateway/guides/access-key-configurations) must allow the provider.
## Upload and use a file
Upload the file, then reference its ID in a request to a model from the same provider.
A file ID only means something to the provider that stored it.
```python OpenAI Python highlight={11} theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx", # Your access key
)
uploaded = client.files.create(
file=open("report.pdf", "rb"),
purpose="user_data",
extra_headers={"Ngrok-AIG-Provider": "openai"},
)
response = client.responses.create(
model="openai:gpt-5.4",
input=[
{
"role": "user",
"content": [
{"type": "input_file", "file_id": uploaded.id},
{"type": "input_text", "text": "Summarize this report in three bullets."},
],
}
],
)
print(response.output_text)
```
```typescript OpenAI TypeScript highlight={10} theme={null}
import fs from "node:fs";
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const uploaded = await client.files.create(
{ file: fs.createReadStream("report.pdf"), purpose: "user_data" },
{ headers: { "Ngrok-AIG-Provider": "openai" } },
);
const response = await client.responses.create({
model: "openai:gpt-5.4",
input: [
{
role: "user",
content: [
{ type: "input_file", file_id: uploaded.id },
{ type: "input_text", text: "Summarize this report in three bullets." },
],
},
],
});
console.log(response.output_text);
```
```python Anthropic Python highlight={10} theme={null}
import anthropic
client = anthropic.Anthropic(
base_url="https://gateway.ngrok.ai",
api_key="ng-xxxxx-g1-xxxxx", # Your access key
)
uploaded = client.beta.files.upload(
file=("report.pdf", open("report.pdf", "rb"), "application/pdf"),
extra_headers={"Ngrok-AIG-Provider": "anthropic"},
)
message = client.beta.messages.create(
model="anthropic:claude-sonnet-4-6",
max_tokens=1024,
betas=["files-api-2025-04-14"],
messages=[
{
"role": "user",
"content": [
{"type": "document", "source": {"type": "file", "file_id": uploaded.id}},
{"type": "text", "text": "Summarize this report in three bullets."},
],
}
],
)
print(message.content[0].text)
```
```bash curl theme={null}
curl https://gateway.ngrok.ai/v1/files \
-H "Authorization: Bearer ng-xxxxx-g1-xxxxx" \
-H "Ngrok-AIG-Provider: openai" \
-F purpose="user_data" \
-F file="@report.pdf"
```
The Anthropic SDK takes the base URL without `/v1`.
The gateway adds the `files-api-2025-04-14` beta flag to Anthropic file requests for you, and keeps any other beta flags you send.
Pass `Ngrok-AIG-Provider` on each file call rather than as a client default header, since inference requests don't need it.
Files work in these request types:
| Endpoint | Where the file ID goes |
| - | - |
| Chat Completions (`/v1/chat/completions`) | A `file` content part: `{"type": "file", "file": {"file_id": "..."}}` |
| Responses (`/v1/responses`) | An `input_file` content part, or a code interpreter tool's `container.file_ids` |
| Messages (`/v1/messages`) | A `document` or `image` block with `"source": {"type": "file", "file_id": "..."}` |
## Paying with credits or your own key
The gateway picks credentials for a file request the same way it does for a model request to that provider: from the [routing rule](/docs/ai-gateway/guides/access-key-configurations) in the access key's configuration.
If the access key has no configuration, or the configuration has no rule for that provider, the gateway uses your stored [provider key](/docs/ai-gateway/guides/attaching-provider-keys) when you have one, and [credits](/docs/ai-gateway/guides/pay-with-credits) otherwise.
Each request uses one credential and doesn't switch partway. A file stored with your own key lives in your provider account, and a file uploaded with credits lives with ngrok.ai, so they're never mixed.
Upload files and send the requests that use them with the same access key, so both go through the same credentials.
To be sure, add a routing rule for the provider to the access key's configuration.
### With your own provider key
Requests go straight through to your provider account:
* Listing returns every file in your provider account, including files you uploaded outside the gateway.
* You can reference any file your provider account holds.
* Expiry, retention, and storage limits are the provider's own.
### When you pay with credits
ngrok.ai stores the file under an ngrok.ai account at the provider and keeps track of which files belong to your account:
* **Expiry**: Files expire 72 hours after upload. On OpenAI, any `expires_after` you send is replaced with that 72-hour expiry.
* **Storage limit**: Your account can hold up to 5 GB of files per provider. Delete files you no longer need to free up room. Expired files stop counting once they're removed, shortly after they expire.
* **Listing**: Listing only returns files your account uploaded with credits. Pages hold at most 100 files. Follow the cursor in the response (`after` for OpenAI, `after_id` for Anthropic) to read the rest. OpenAI's `order=asc` and Anthropic's `before_id` aren't supported.
* **Using files**: A request can only reference files your account uploaded with credits. If a request references any other file ID, the gateway won't use credits for that model. It uses your own provider key for that provider if one is routed, and otherwise returns [`ERR_NGROK_27240`](/docs/ai-gateway/reference/error-codes#err_ngrok_27240).
## Limits
* **File size**: An upload can be at most 512 MiB, whichever credentials it uses.
* **Timeout**: A transfer must finish within your account's total timeout, 120 seconds by default. Raise it in [Account Settings](/docs/ai-gateway/guides/account-settings) for large files on slow connections.
* **Credits**: Uploads, listings, metadata, and downloads need a positive [credit](/docs/ai-gateway/concepts/credits) balance, but they don't spend credits. Deletes work at a zero balance, so you can always free storage.
## Errors
File errors use the provider's error format, so your SDK raises its usual exception. A request that doesn't name a provider gets the OpenAI format.
| Code | Status | What happened |
| - | - | - |
| `ERR_NGROK_27240` | 404 | A model request referenced files your account didn't upload with credits. |
| `ERR_NGROK_27241` | 400 | The request is missing the `Ngrok-AIG-Provider` header. |
| `ERR_NGROK_27242` | 400 | The provider in `Ngrok-AIG-Provider` doesn't support the Files API. |
| `ERR_NGROK_27243` | 400 | The list `limit` isn't a whole number from 1 to 100. |
| `ERR_NGROK_27244` | 404 | Your account has no file with that ID for that provider. |
| `ERR_NGROK_27245` | 400 | A list parameter isn't supported when you pay with credits, such as OpenAI's `order=asc` or Anthropic's `before_id`. |
| `ERR_NGROK_27246` | 413 | The upload would put your account over its storage limit for that provider. |
| `ERR_NGROK_27247` | 400 | The upload isn't a `multipart/form-data` request. |
| `ERR_NGROK_27248` | 413 | The upload is larger than 512 MiB. |
See [Error codes](/docs/ai-gateway/reference/error-codes) for every gateway error.
## Next steps
* [Pay with credits](/docs/ai-gateway/guides/pay-with-credits): Call providers without your own provider keys
* [Bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys): Use files stored in your provider account
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations): Control which credentials a request uses
# Configure provider key failover
Source: https://ngrok.com/docs/ai-gateway/guides/key-selection-failover
Try another provider key when one hits a rate limit, quota limit, or auth error.
Configure multiple provider keys in an [access key configuration](/docs/ai-gateway/guides/access-key-configurations) routing rule. The gateway tries keys in order when one hits a rate limit, runs out of quota, or fails authentication.
## How failover works
When a routing rule step lists multiple provider keys:
1. The gateway tries the first key.
2. On a rate limit (429), or an auth failure (401 or 403) because the provider rejected the key, it tries the next key.
3. When no keys are left, the gateway falls back to paying with credits if the rule has an `ngrok` step after this one. Otherwise it moves to the next model you listed, or returns the last error.
Server errors (5xx), timeouts, and connection failures don't try the next key. Another key for the same provider would likely fail the same way, so the gateway moves straight to the next model you listed. To fail over on those errors, add [fallback models](/docs/ai-gateway/guides/configure-fallback-models).
Failover is configured per provider in the access key configuration—not in your application code.
## Via dashboard
1. [Add multiple provider keys](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) for the same provider.
2. [Edit an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration).
3. Add or edit a routing rule for the provider.
4. Attach multiple keys to the **Bring your own API key** step in the order you want them tried.
## Via the AI Gateway API
```bash theme={null}
curl -X POST https://api.ngrok.ai/access-key-configurations \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "OpenAI with failover",
"router": {
"rules": [
{
"provider": "openai",
"steps": [
{
"type": "user",
"keySelectionStrategy": "ordered",
"keys": [
{ "id": "aigpk_primary" },
{ "id": "aigpk_backup" }
]
}
]
}
]
}
}'
```
See the [Access Key Configurations API reference](/docs/ai-gateway/api-reference/access-key-configurations/create).
Assign the configuration to your access key. Your app sends only the access key:
```python theme={null}
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
```
## Next steps
* [Bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys): Store upstream credentials
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations): Routing rules and scope
* [How It Works](/docs/ai-gateway/how-it-works): Full request flow
# Choose a model
Source: https://ngrok.com/docs/ai-gateway/guides/model-selection-strategies
Choose a model by ID or route to a specific provider.
When you send a request to `https://gateway.ngrok.ai`, the `model` field tells the AI Gateway which model to call.
Use a model ID when you want the gateway to resolve the provider from the [model catalog](/docs/ai-gateway/reference/model-catalog). Use `provider:model` when you want to choose the provider yourself.
## Use a model ID
Use a model ID when you know which model you want to call and don't need to force a specific provider.
```json theme={null}
{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}]
}
```
The gateway looks up `gpt-4o` in the [model catalog](/docs/ai-gateway/reference/model-catalog) and finds every provider that serves it. It tries the model author's own provider first (OpenAI here), then any reseller that serves the same model, such as OpenRouter. Providers your access key can't use drop out.
## Route to a specific provider
Use `provider:model` when you want predictable routing or need to avoid ambiguity between model names.
```json theme={null}
{
"model": "openai:gpt-4o",
"messages": [{"role": "user", "content": "Hello"}]
}
```
In this example:
* `openai` is the provider ID.
* `gpt-4o` is the model ID.
Use this format when you have more than one provider configured, want to call a custom provider, or want the request to go to one specific upstream.
## Let ngrok.ai choose
Set `model` to `ngrok/auto` to let ngrok.ai pick a model for each request, starting with the cheapest one that fits the prompt. See [Automatic model selection](/docs/ai-gateway/guides/automatic-model-selection).
## Use a custom provider model
```json theme={null}
{
"model": "my-ollama:llama3.2",
"messages": [{"role": "user", "content": "Hello"}]
}
```
Custom providers use the same `provider:model` format. In this example, `my-ollama` is your custom provider ID and `llama3.2` is the model ID configured on that provider.
## Check model capabilities
Before choosing a model, check the [model catalog](/docs/ai-gateway/reference/model-catalog) for:
| Field | Use it to check |
| - | - |
| Context window | How much input the model can accept |
| Output tokens | How much output the model can return |
| Modalities | Whether the model supports text, image, audio, video, or files |
| Provider key required | Whether you need to bring your own provider key |
## Keep access rules in mind
The request can only use providers and models allowed by the [access key configuration](/docs/ai-gateway/guides/access-key-configurations) assigned to the access key.
If you need to limit what a client can call, see [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models).
## Next steps
* [Model catalog](/docs/ai-gateway/reference/model-catalog): Built-in providers and models
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model if the first one fails
* [Automatic model selection](/docs/ai-gateway/guides/automatic-model-selection): Let ngrok.ai pick the model
* [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself): Connect Ollama, vLLM, LM Studio, or another private model
# Pay with credits
Source: https://ngrok.com/docs/ai-gateway/guides/pay-with-credits
Call supported providers without adding provider keys.
Pay with credits when you want the AI Gateway to supply the provider credentials for you, so you don't need a provider account.
Your app sends an [access key](/docs/ai-gateway/concepts/access-keys) to the gateway. The gateway authenticates to the supported upstream provider, and credits cover the model cost plus the gateway processing fee.
You can pay with credits for models from OpenAI, Anthropic, Google, DeepSeek, xAI, Moonshot AI, Z.ai, and other built-in providers. Availability is per model; the [model catalog](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials) shows which providers support it. For providers that require your own credentials, [bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys).
## What you'll need
* An ngrok account.
* An [access key](/docs/ai-gateway/concepts/access-keys) from [app.ngrok.ai](https://app.ngrok.ai).
* Credits in your AI Gateway account.
## Create an access key
Create an access key in [app.ngrok.ai](https://app.ngrok.ai). Use this key as the API key in your SDK.
The access key authenticates your application to the gateway. It is different from a provider key, which authenticates the gateway to an upstream provider.
## Call a supported OpenAI model
```json theme={null}
{
"model": "openai:gpt-4o",
"messages": [{"role": "user", "content": "Hello"}]
}
```
You can also use the model ID directly:
```json theme={null}
{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}]
}
```
## Call a supported Anthropic model
```json theme={null}
{
"model": "anthropic:claude-sonnet-4-6",
"messages": [{"role": "user", "content": "Hello"}]
}
```
## How billing works
When you pay with credits, credits cover:
* The upstream model cost.
* Hosted tools the provider bills, such as web search, code execution, and image generation.
* The AI Gateway processing fee.
Before sending a request, the gateway checks that you can pay for it with credits. If you can't pay for a model or feature with credits, you get an error asking you to add your own provider key. See [`ERR_NGROK_27238`](/docs/ai-gateway/reference/error-codes#err_ngrok_27238).
For providers or models you can't pay for with credits, or when you want usage billed directly by the provider, [bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys).
## When to bring your own key instead
Bring your own provider key when:
* You already have a provider account.
* You want usage billed directly by the provider.
* You have negotiated provider pricing.
* You need a provider or model that requires your own credentials.
## Next steps
* [Credits](/docs/ai-gateway/concepts/credits): Learn how credits work
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Choose model IDs and provider-qualified models
* [Bring your own provider key](/docs/ai-gateway/guides/attaching-provider-keys): Use your own upstream provider credentials
# Restrict providers and models
Source: https://ngrok.com/docs/ai-gateway/guides/restrict-providers-and-models
Limit which providers and models an access key can call.
Use access key configurations to control which providers and models an access key can call.
Restrictions are checked before the gateway routes a request upstream. That means a request can fail fast if a client asks for a provider or model the key shouldn't use.
## What you'll need
* An [access key](/docs/ai-gateway/concepts/access-keys).
* An [access key configuration](/docs/ai-gateway/guides/access-key-configurations).
* The provider IDs and model IDs you want to allow.
## Allow specific providers
Use provider restrictions when an access key should only call certain providers.
```json theme={null}
{
"access": {
"providers": {
"allow": ["openai", "anthropic"]
}
}
}
```
With this configuration, requests can only route to OpenAI or Anthropic.
## Allow specific models
Use model restrictions when an access key should only call certain models.
```json theme={null}
{
"access": {
"models": {
"allow": ["openai/gpt-4o", "anthropic/claude-sonnet-4-6"]
}
}
}
```
Model entries accept three forms:
| Entry | Matches |
| - | - |
| `gpt-4o` | The model on any provider that serves it |
| `openai/gpt-4o` | The catalog ID (author and model). Matches that model on any provider that serves it, including resellers such as OpenRouter |
| `openai:openai/gpt-4o` | That model on the `openai` provider only |
Use the `provider:` prefix when you always want to use that provider. Combine model rules with a provider allowlist to block resellers.
## Allow providers and models together
Combine provider and model restrictions when you want a key to stay within a small set of approved providers and models.
```json theme={null}
{
"access": {
"providers": {
"allow": ["openai", "anthropic"]
},
"models": {
"allow": ["openai/gpt-4o", "anthropic/claude-sonnet-4-6"]
}
}
}
```
Requests outside the allowed providers or models are rejected before they reach an upstream provider.
## How this works with fallback
Every model in a fallback request must be allowed.
```json theme={null}
{
"model": "openai:gpt-4o",
"models": ["anthropic:claude-sonnet-4-6"],
"messages": [{"role": "user", "content": "Hello"}]
}
```
If the primary model is allowed but the fallback model is not, the gateway drops the fallback and names it in the `Ngrok-AIG-Rejected-Models` response header. The request fails only when none of the models you listed are allowed.
## Common patterns
| Goal | Configuration |
| - | - |
| Allow only OpenAI | Allow provider `openai` |
| Allow only Claude Sonnet | Allow model `anthropic/claude-sonnet-4-6` |
| Give a team access to two providers | Allow both provider IDs |
| Block expensive models | Allow only approved model IDs |
| Limit a custom provider | Allow the custom provider ID and model IDs |
## Next steps
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations): Full configuration flow
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Use model IDs in requests
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Use allowed fallback models
# Secure your gateway
Source: https://ngrok.com/docs/ai-gateway/guides/securing-endpoints
How access keys provide built-in authorization for the AI Gateway.
[Access keys](/docs/ai-gateway/concepts/access-keys) authenticate every request to `https://gateway.ngrok.ai`. The AI Gateway validates each key before forwarding traffic. Upstream provider credentials are managed separately—see [Access keys vs provider keys](/docs/ai-gateway/concepts/access-keys#access-keys-vs-provider-keys).
## How it works
1. [Create an access key](/docs/ai-gateway/concepts/access-keys) in [app.ngrok.ai](https://app.ngrok.ai) or via the AI Gateway API
2. Send the key as `Authorization: Bearer ng-xxxxx-g1-xxxxx` (OpenAI-compatible APIs) or `x-api-key` (Anthropic native API)
3. The gateway validates the key on every request
4. Invalid or missing keys are rejected—requests do not reach providers
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
```
The AI Gateway replaces your access key with provider credentials from your configuration before forwarding to the upstream provider.
## Per-client keys
Create separate access keys for each client or application:
* Revoke one client without affecting others
* Track usage per key
* Assign different [configurations](/docs/ai-gateway/guides/access-key-configurations) to limit scope per client
Create access keys with the [Access Keys API](/docs/ai-gateway/api-reference/access-keys/create). Authorize the request with your [AI Gateway API key](/docs/ai-gateway/concepts/access-keys#credentials-overview).
```bash theme={null}
curl -X POST https://api.ngrok.ai/access-keys \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Production web app" }'
```
Delete access keys with the [Access Keys API](/docs/ai-gateway/api-reference/access-keys/delete). Authorize the request with your [AI Gateway API key](/docs/ai-gateway/concepts/access-keys#credentials-overview).
```bash theme={null}
curl -X DELETE https://api.ngrok.ai/access-keys/aigk_xxxxx \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY"
```
See the [Access Keys API reference](/docs/ai-gateway/api-reference/access-keys/delete).
Deletion is permanent. Clients using the revoked key receive authentication errors immediately.
## Protecting provider keys
Store provider keys in app.ngrok.ai and reference them in configurations. Clients only ever hold the access key.
See [Provider Keys](/docs/ai-gateway/guides/attaching-provider-keys).
## Next steps
* [Access Keys](/docs/ai-gateway/concepts/access-keys): Create and manage keys
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations): Scope and credentials per key
* [Error Codes](/docs/ai-gateway/reference/error-codes): Authentication errors
# Use a model you run yourself
Source: https://ngrok.com/docs/ai-gateway/guides/use-a-model-you-run-yourself
Connect Ollama, vLLM, LM Studio, or another private model endpoint to the AI Gateway.
Use a custom provider when you want the AI Gateway to call a model running on your machine, private network, or cloud GPU.
Custom providers can point to self-hosted tools like Ollama, vLLM, LM Studio, or any OpenAI- or Anthropic-compatible API.
## What you'll need
Your model server must:
1. Expose a supported API surface, such as OpenAI Chat Completions, OpenAI Responses, or Anthropic Messages.
2. Be reachable from the AI Gateway.
3. Have at least one model ID configured on the provider.
## Connect a local model with an internal endpoint
If your model runs on your machine or private network, expose it with an ngrok internal endpoint.
For example, if your model server listens on port `11434`:
```bash theme={null}
ngrok http 11434 --url https://my-ollama.internal
```
Use the internal endpoint URL as the custom provider base URL.
Internal endpoints (`.internal` domains) are private to your ngrok account, meaning they're not reachable from the public internet. Use the same ngrok account here and in the AI Gateway, otherwise the gateway can't reach the endpoint.
## Create a custom provider
In [app.ngrok.ai](https://app.ngrok.ai):
1. Go to **Providers**.
2. Open the **Custom** tab.
3. Select **Add provider**.
4. Choose **External URL** or **Local**.
5. Enter a provider ID, base URL, API format, and model IDs.
6. Add a provider key if the upstream requires authentication.
## Create a custom provider with the API
```bash theme={null}
curl -X POST https://api.ngrok.ai/providers \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"providerId": "my-ollama",
"name": "Local Ollama",
"baseUrl": "https://my-ollama.internal",
"supportedApiSurfaces": [
{ "format": "openai", "surface": "chat-completions" }
],
"models": [{ "modelId": "llama3.2" }]
}'
```
See the [Providers API reference](/docs/ai-gateway/api-reference/providers/create) for every field.
## Allow the provider on an access key
An access key without a configuration can call a custom provider as soon as you create it. If you haven't added a provider key, the gateway sends the request without credentials. An access key with a configuration can call the provider only when the configuration's access scope allows it.
To route authenticated traffic to the provider, or to control which access keys can call it:
1. Add a provider key if the upstream requires authentication.
2. Create or update an [access key configuration](/docs/ai-gateway/guides/access-key-configurations).
3. Allow the custom provider ID.
4. Assign the configuration to an [access key](/docs/ai-gateway/concepts/access-keys).
## Call the model
Use `provider:model` in the request.
```json theme={null}
{
"model": "my-ollama:llama3.2",
"messages": [{"role": "user", "content": "Hello"}]
}
```
## URL requirements
| URL type | Scheme | Example |
| - | - | - |
| External | `https://` only | `https://api.example.com/v1` |
| ngrok internal | `http://` or `https://` | `https://my-ollama.internal` |
HTTP is only allowed for ngrok `.internal` endpoints. External URLs must use HTTPS.
## Next steps
* [Ollama guide](/docs/ai-gateway/custom-providers/ollama): Connect Ollama
* [vLLM guide](/docs/ai-gateway/custom-providers/vllm): Connect vLLM
* [Provider keys](/docs/ai-gateway/guides/attaching-provider-keys): Store upstream credentials
* [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models): Allow the custom provider on a key
# Find out why a request failed over
Source: https://ngrok.com/docs/ai-gateway/guides/why-a-request-failed-over
Trace one AI Gateway request through every upstream attempt to see which providers it tried, in what order, and which one served it.
The AI Gateway may make several attempts before returning a response. The response alone doesn’t show how many attempts were made. This guide shows you how to use a response header to find each attempt and see what happened.
## 1. Read the attempt count off the response
Every response where the gateway tried at least one provider includes the `Ngrok-AIG-Attempts` header, which shows how many attempts were made. A value greater than `1` means the first attempt failed and the gateway tried again.
```bash theme={null}
curl -i https://gateway.ngrok.ai/v1/chat/completions \
-H "Authorization: Bearer $NGROK_AI_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"models": ["anthropic:claude-sonnet-4-5", "google:gemini-3.6-flash"],
"messages": [{"role": "user", "content": "Hello"}]
}'
```
```http theme={null}
HTTP/2 200
ngrok-aig-request-id: rq_2abcDEF456
ngrok-aig-attempts: 3
ngrok-aig-model: gemini-3.6-flash
```
The AI Gateway made three attempts. The third candidate in the list handled the request after the first two candidates failed.
Use the `Ngrok-AIG-Model` response header to identify the model that handled your request. The AI Gateway passes the provider’s response body through unchanged, including its `model` field. If the gateway switches models after a failed attempt, these values may differ. Use the header as the source of truth.
## 2. Look the request up by ID
Pass the `Ngrok-AIG-Request-Id` value to the attempts endpoint:
```bash theme={null}
curl https://api.ngrok.ai/usage/requests/rq_2abcDEF456 \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY"
```
You get every upstream attempt for that request, ordered by attempt number:
```json theme={null}
{
"uri": "https://api.ngrok.ai/usage/requests/rq_2abcDEF456",
"requestId": "rq_2abcDEF456",
"attempts": [
{
"event": {
"attemptNumber": 1,
"provider": "openai",
"model": "gpt-4o",
"statusCode": 401,
"isError": true,
"keySource": "user"
},
"served": false,
"retryAction": "next_key",
"completion": "failed",
"upstreamDurationMs": 88
},
{
"event": {
"attemptNumber": 2,
"provider": "openai",
"model": "gpt-4o",
"statusCode": 429,
"isError": true,
"keySource": "user"
},
"served": false,
"retryAction": "next_backend",
"completion": "failed",
"upstreamDurationMs": 214
},
{
"event": {
"attemptNumber": 3,
"provider": "anthropic",
"model": "claude-sonnet-4-6",
"statusCode": 200,
"isError": false,
"keySource": "ngrok"
},
"served": true,
"retryAction": "succeeded",
"completion": "succeeded",
"upstreamDurationMs": 1902
}
]
}
```
This endpoint lets you only view requests from your account. It cannot modify them. If a request belongs to another account, the endpoint returns “not found” instead of “forbidden.”
## 3. Check why the AI Gateway retried or stopped
For each attempt, check `completion` to see how it ended and `retryAction` to see what the AI Gateway decided to do next. Use `served` to identify the attempt that returned the response to your client.
### Identify the attempt that returned the response
Look for `served: true`. At most one attempt per request has this value.
Do not assume the last attempt returned a response. A request can end with a failed attempt that did not produce a response for your client.
### Check how each attempt ended
The `completion` field has one of these values:
* `succeeded`
* `failed`
* `timed_out`
* `stream_failed`
* `unknown`
For failed attempts, read the error details to find the cause, then check `retryAction` to understand why the gateway retried or stopped.
### Follow the retry decisions
| `retryAction` | What happened |
| - | - |
| `succeeded` | The attempt produced the response your client received. |
| `next_key` | The credential failed authentication, so the gateway tried the next key for the same provider. |
| `next_quota_pool` | The credential’s quota pool was exhausted, so the gateway moved to another pool. |
| `next_backend` | The provider or model failed, so the gateway tried the next model in the failover list. |
| `managed_fallback` | A customer-owned key failed, so the gateway switched to an ngrok-managed key. |
| `retry_same_backend` | The provider requested a retry using `Retry-After`, so the gateway waited and retried the same backend. |
| `fail_fast` | The failure could not be retried, so the gateway stopped. |
| `exhausted` | No candidates remained to try. |
`retryAction` is optional. It is absent from attempts recorded before the gateway began storing retry decisions.
In the example above, `next_key` on attempt 1 means the first OpenAI key failed authentication, so the gateway tried the second OpenAI key. That key hit a rate limit and no keys were left, so `next_backend` on attempt 2 means the gateway moved to the next model in the failover list. Check each attempt’s error details to see why it failed.
## What this tells you to change
| Pattern down the chain | What to do |
| - | - |
| `next_key` on every OpenAI attempt | Add more [provider keys](/docs/ai-gateway/guides/attaching-provider-keys) for that provider, or raise your quota with them |
| `next_backend` on the first candidate every time | Your primary model is the wrong default. Reorder the [fallback list](/docs/ai-gateway/guides/configure-fallback-models) |
| A single `fail_fast` attempt | The request itself was rejected. Check the status code and the [error code](/docs/ai-gateway/reference/error-codes); failover would not have helped |
| `exhausted` at the end | Every candidate failed. Widen the candidate list or attach credentials for more providers |
| `managed_fallback` you did not expect | Your own key is failing and ngrok.ai credits are absorbing the traffic. Check the key |
## What this endpoint does not include
This endpoint does not include captured request and response bodies, which could contain sensitive information.
## Next steps
How failover decides what to try next
Diagnose a failure from the response alone
# How It Works
Source: https://ngrok.com/docs/ai-gateway/how-it-works
Understand the ngrok.ai request flow and failover behavior.
## Request flow
When you send a request to `https://gateway.ngrok.ai`:
```mermaid theme={null}
sequenceDiagram
participant Client
participant Gateway as gateway.ngrok.ai
participant Provider as AI Provider
Client->>Gateway: POST /v1/chat/completions (access key)
Gateway->>Gateway: Validate access key
Gateway->>Gateway: Apply configuration and select model
Gateway->>Provider: Forward request (injected credentials)
Provider-->>Gateway: Response (or error)
Gateway-->>Client: Return response
```
1. **Your app sends a request** with your [access key](/docs/ai-gateway/concepts/access-keys) to `https://gateway.ngrok.ai`
2. **The gateway validates the key** and loads its [access key configuration](/docs/ai-gateway/guides/access-key-configurations)
3. **The gateway resolves the model** from your request body
4. **Provider credentials are selected** from the configuration's routing rules: a key ngrok.ai supplies when you pay with credits, or your stored [provider keys](/docs/ai-gateway/guides/attaching-provider-keys)
5. **Unsupported parameters are stripped** for the chosen model before forwarding, and listed in the `Ngrok-AIG-Removed-Params` [response header](#response-headers)
6. **The request is forwarded** to the upstream provider
7. **On failure, the gateway retries** with the next provider key or model candidate
8. **The response is returned** to your app and usage is recorded
Manage keys, configurations, providers, and credits at [app.ngrok.ai](https://app.ngrok.ai). Your apps send traffic to `gateway.ngrok.ai`.
## Authentication
Every request must include a valid **access key**. Send it as `Authorization: Bearer ng-xxxxx-g1-xxxxx` (OpenAI-compatible APIs) or `x-api-key` (Anthropic native API).
Provider keys stay in [app.ngrok.ai](https://app.ngrok.ai). The AI Gateway injects those from your configuration after validating the access key.
## Response headers
Every response from `gateway.ngrok.ai` carries ngrok's own headers describing how the gateway handled the request.
| Header | Value | When present |
| - | - | - |
| `Ngrok-AIG-Request-Id` | The request's ID. Use it to look the request up afterwards. | Every response, including rejections and errors. |
| `Ngrok-AIG-Attempts` | How many upstream attempts the gateway made. | Once the gateway tries a provider, on both success and failure. Absent when the request failed before any attempt, such as a malformed body or an unknown model. |
| `Ngrok-AIG-Model` | The upstream model that produced the response. | Success only. |
| `Ngrok-AIG-Rejected-Models` | Comma-separated models from your request that never ran, for example because the access scope blocks them or no credentials are available. Lists at most 4 models. | Once the gateway tries a provider, when at least one requested model was dropped. |
| `Ngrok-AIG-Removed-Params` | Comma-separated request fields the gateway didn't send to the provider that served the response, because that provider or model doesn't support them. | Success only, when the gateway removed at least one field. |
All five are exposed through CORS, so browser clients can read them.
These are ngrok's headers rather than the provider's, so a managed-key caller and a [Bring Your Own Keys](/docs/ai-gateway/concepts/bring-your-own-keys) caller see the same values.
Provider rate-limit headers behave differently: the gateway forwards those only when the attempt used your own provider key.
### The model header is authoritative
The gateway passes the response body through byte-for-byte.
The `model` or `modelVersion` field inside the body is the provider's own word and is never rewritten to name the model that served the response.
On a multi-model failover the body can therefore name a different model than the header.
Read `Ngrok-AIG-Model` when you need to know what answered.
### Streamed responses
On a streamed response the headers commit with the first flushed byte.
The attempt count is final at that point, because the gateway cannot retry once bytes have reached your client.
### Trace IDs are not a substitute
`Ngrok-Trace-Id` is emitted only when the trace is sampled, it is not exposed through CORS, and it identifies the whole client request rather than a single attempt.
Use `Ngrok-AIG-Request-Id` to identify a request.
## Model selection
The gateway determines which model and provider to use from your request.
| Model in request | What happens |
| - | - |
| `gpt-4o` | Catalog lookup → OpenAI first, then other providers that serve the same model |
| `openai:gpt-4o` | Explicit OpenAI routing |
| `your-provider:your-model` | A [model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself) |
| `models` array | Fail over through listed models in order |
| `ngrok/auto` | ngrok.ai picks a model for each request. See [Automatic model selection](/docs/ai-gateway/guides/automatic-model-selection) |
To choose model IDs and provider-qualified model names, see [Choose a model](/docs/ai-gateway/guides/model-selection-strategies).
## Access key configurations
Configurations define:
* **Access scope**: allowed providers and models
* **Routing rules**: pay with credits or use your own provider keys, per provider
When a configuration has no routing rule for a provider, requests to that provider are paid with credits only. Stored provider keys are not used without a rule.
An access key without a configuration uses allow-all scope. Built-in models you can [pay for with credits](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials) use an ngrok.ai key by default when you have [credits](/docs/ai-gateway/concepts/credits).
## Failover
The gateway retries automatically when upstream requests fail.
### What triggers failover?
* Rate limits (HTTP 429)
* Auth errors (HTTP 401 or 403) because the provider rejected the key
* Timeouts, server errors (HTTP 5xx), and connection failures
Other 4xx errors return to your client right away, because another model would fail the same way.
### Failover order
What the gateway tries next depends on the error:
* **Auth error or rate limit**: the next provider key in the routing rule step. When no keys are left and the rule has an `ngrok` step after the **Bring your own API key** step, the gateway falls back to paying with credits.
* **Timeout, server error, or connection failure**: the gateway skips the remaining keys for that provider and moves to the next model.
The next model comes from your request's `models` array, or from another provider that serves the same model. See [Handle gateway errors](/docs/ai-gateway/guides/error-handling) for the full order.
A routing rule uses the first step that has usable credentials. The gateway doesn't try later steps, except an `ngrok` step after a **Bring your own API key** step.
To attach several provider keys and control the order they're tried, see [Multi-key failover](/docs/ai-gateway/guides/key-selection-failover).
## Timeouts and token limits
Configure account-level limits in [Account Settings](/docs/ai-gateway/guides/account-settings).
| Setting | Default | Description |
| - | - | - |
| Per-request timeout | 60s | Max time for a single upstream attempt |
| Total timeout | 120s | Max time including all failover attempts |
| Max input tokens | none | Reject requests exceeding estimated input tokens |
| Max output tokens | none | Cap completion length |
Streaming responses get more time after the first byte: up to 15 minutes with the default total timeout, as long as the provider keeps sending data at least every 30 seconds. See [Streaming responses](/docs/ai-gateway/guides/account-settings#streaming-responses).
Request bodies are limited to 32 MiB.
## Next steps
Create keys to authenticate requests
Scope and route traffic per key
Model IDs, provider prefixes, and custom provider models
How the gateway handles failures
# Observability Overview
Source: https://ngrok.com/docs/ai-gateway/observability/index
Monitor and debug AI Gateway requests.
Monitor AI Gateway usage from [app.ngrok.ai](https://app.ngrok.ai) and the AI Gateway API.
Query usage events and aggregated overview via the AI Gateway API
Troubleshoot failed requests and error codes
Reference for gateway error responses
## Identify a request
Every gateway response carries `Ngrok-AIG-Request-Id`, plus headers such as `Ngrok-AIG-Attempts`, `Ngrok-AIG-Model`, `Ngrok-AIG-Rejected-Models`, and `Ngrok-AIG-Removed-Params` that describe how the request was served.
Record the request ID in your application logs so you can tie a client-side failure to gateway usage data later.
See [Response headers](/docs/ai-gateway/how-it-works#response-headers).
## Usage API
Query usage with the AI Gateway API:
```bash theme={null}
curl "https://api.ngrok.ai/usage/overview?startTime=2026-10-01T00:00:00Z&groupBy=accessKey" \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY"
```
The overview returns daily cost, request, and error series for the window. `startTime` is required. Group by `provider` (the default) or `accessKey`.
[List individual usage events](/docs/ai-gateway/api-reference/usage/list) to see one record per upstream attempt.
Each event reports the provider, model, status code, token counts, and a per-attempt cost breakdown.
Attempts of the same client request share a `requestId`.
By default the list returns only each request's terminal attempt.
Pass `includeRetries=true` to see the retries the gateway made along the way.
When a provider reports no usage of its own, `usageEstimated` is `true` and the provider-reported token fields are all zero.
Read `inputTokensEstimate` and `outputTokensEstimate` on those attempts instead.
## Look up one request
To see every attempt the gateway made for one request, pass its `Ngrok-AIG-Request-Id` to [`GET /usage/requests/{requestId}`](/docs/ai-gateway/api-reference/usage/request-attempts). See [Why a request failed over](/docs/ai-gateway/guides/why-a-request-failed-over).
## Logs in app.ngrok.ai
The [Logs](https://app.ngrok.ai/usage) page in app.ngrok.ai lists recent requests. Open a request to see its attempts. If you turn on [request capture](/docs/ai-gateway/guides/account-settings#request-capture), the request detail also shows the captured headers and bodies.
**Have feedback?** Email [niji@ngrok.ai](mailto:niji@ngrok.ai) with observability requests.
# AI Gateway Overview
Source: https://ngrok.com/docs/ai-gateway/overview
Route requests to AI providers with automatic failover, load balancing, and observability.
The ngrok AI Gateway ([ngrok.ai](https://ngrok.ai)) enables your applications to call both hosted AI providers and local models through a single endpoint. Control who has access, decide what they can call, and choose whether requests use credits, your provider keys, or a model you run yourself.
## Why use the AI Gateway?
Use OpenAI, Anthropic, Google, DeepSeek, xAI, and other built-in providers with an access key and credits. No provider signup required.
Route to local models like Ollama or vLLM alongside cloud providers with [a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself).
If one provider or key fails, ngrok.ai automatically tries the next model or key.
Works with official and third-party SDKs. Point the base URL at `gateway.ngrok.ai` and use your access key.
## Quick example
Sign up at [app.ngrok.ai](https://app.ngrok.ai) and point your SDK at the gateway with your [access key](/docs/ai-gateway/concepts/access-keys):
```python Python (OpenAI) highlight={4-5} theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
```
```python Python (Anthropic) highlight={4-5} theme={null}
import anthropic
client = anthropic.Anthropic(
base_url="https://gateway.ngrok.ai",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
)
```
```typescript TypeScript (OpenAI) highlight={4-5} theme={null}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx" // Your access key
});
const response = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Hello!" }]
});
```
```typescript TypeScript (Anthropic) highlight={4-5} theme={null}
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://gateway.ngrok.ai",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const message = await client.messages.create({
model: "claude-opus-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }],
});
```
```bash cURL (OpenAI) highlight={3} theme={null}
curl https://gateway.ngrok.ai/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ng-xxxxx-g1-xxxxx" \
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello!"}]
}'
```
```bash cURL (Anthropic) highlight={3} theme={null}
curl https://gateway.ngrok.ai/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: ng-xxxxx-g1-xxxxx" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-opus-4-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello!"}]
}'
```
You don't need to sign up for OpenAI or bring your own OpenAI key to make this request. Your ngrok.ai credits will cover any provider costs.
Every request consumes [credits](/docs/ai-gateway/concepts/credits). No subscription plan required to get started. See [Credits](/docs/ai-gateway/concepts/credits) for more details and when you might need a ngrok subscription for features like team members or internal endpoints.
On each request, the AI Gateway:
1. Receives your request with your access key at `gateway.ngrok.ai`
2. Validates the key and loads your account configuration
3. Selects which model and provider to use
4. Forwards the request using a key ngrok.ai supplies (paid with credits) or your provider keys
5. Retries with the next key or model on failure
6. Returns the response
## What can you do?
| Use Case | Description |
| - | - |
| **Use without provider accounts** | Get started with OpenAI, Anthropic, Google, and [other providers](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials) using an access key and [credits](/docs/ai-gateway/concepts/credits) |
| **Per-key routing** | [Access key configurations](/docs/ai-gateway/guides/access-key-configurations) scope providers, models, and credentials |
| **Multi-model failover** | List multiple models in a request; the gateway tries each in order |
| **Multi-key failover** | Attach multiple provider keys in a configuration routing rule |
| **Self-hosted models** | Route to Ollama, vLLM, or other servers with [a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself) |
## Next steps
Get ngrok.ai integrated in 5 minutes
Learn about managing access to ngrok.ai
Request flow and failover behavior
Connect your application to ngrok.ai
Use your own provider API keys for providers
Manage keys, providers, settings, and usage from your own code
# Anthropic
Source: https://ngrok.com/docs/ai-gateway/providers/anthropic
Use Anthropic Claude models through the ngrok AI Gateway.
This guide walks through using [Anthropic](https://anthropic.com) Claude models with the AI Gateway. Anthropic is a **built-in provider** you can pay for with credits, so you can use Claude models without an Anthropic account of your own, or bring your own key.
## Pay with credits (no Anthropic account)
You can use Claude models without your own Anthropic account. ngrok.ai supplies the Anthropic credentials and bills the model cost to your credits.
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an [access key](/docs/ai-gateway/concepts/access-keys) and purchase [credits](/docs/ai-gateway/concepts/credits) in [app.ngrok.ai](https://app.ngrok.ai).
Point your SDK at the gateway with your access key:
```python Python theme={null}
import anthropic
client = anthropic.Anthropic(
base_url="https://gateway.ngrok.ai",
api_key="ng-xxxxx-g1-xxxxx", # Access key
)
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
)
```
```bash cURL theme={null}
curl https://gateway.ngrok.ai/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: ng-xxxxx-g1-xxxxx" \
-H "anthropic-version: 2023-06-01" \
-d '{"model": "claude-sonnet-4-6", "max_tokens": 1024, "messages": [{"role": "user", "content": "Hello!"}]}'
```
The gateway supports both the Anthropic Messages API (`/v1/messages`) and OpenAI-compatible Chat Completions.
## Bring your own Anthropic key
Want requests billed to your own Anthropic account instead of through credits? Store your Anthropic key once—the gateway attaches it for you on every request.
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an [access key](/docs/ai-gateway/concepts/access-keys) in [app.ngrok.ai](https://app.ngrok.ai) if you don't have one yet.
[Add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) for Anthropic. ngrok stores it encrypted, so it never has to live in your application or get shared around—and you can reuse it across as many access keys as you need.
[Create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with an Anthropic routing rule set to **Bring your own API key**, then assign it to your access key.
Your code doesn't change. Send the same access key as before—the gateway swaps in your Anthropic key before the request leaves for Anthropic.
## Explicit provider routing
```python theme={null}
message = client.messages.create(
model="anthropic:claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
)
```
## Available models
Browse the [model catalog](/docs/ai-gateway/reference/model-catalog#anthropic) for the full list of Claude models you can call through the gateway.
## Files
Anthropic also supports the [Files API](/docs/ai-gateway/guides/files) for uploading documents and images once and referencing them by ID.
## Next steps
* [Access Keys](/docs/ai-gateway/concepts/access-keys)
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations)
* [Provider Keys](/docs/ai-gateway/guides/attaching-provider-keys)
# DeepSeek
Source: https://ngrok.com/docs/ai-gateway/providers/deepseek
Use DeepSeek models through the ngrok AI Gateway.
[DeepSeek](https://www.deepseek.com) provides high-performance reasoning and chat models.
DeepSeek supports Chat Completions, Responses, and Anthropic Messages requests.
DeepSeek is a **built-in provider** you can pay for with credits, so a provider key is optional.
Add your own DeepSeek key to bill usage to your DeepSeek account instead of your ngrok.ai credits.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key and purchase [credits](/docs/ai-gateway/concepts/credits) in [app.ngrok.ai](https://app.ngrok.ai).
Skip this step to pay with credits.
To bring your own key, sign up at [platform.deepseek.com](https://platform.deepseek.com) and create an API key. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) and [create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with a `deepseek` routing rule that uses it.
Send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[{"role": "user", "content": "Hello!"}]
)
```
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#deepseek).
## Next steps
* [Provider Keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations)
# Google
Source: https://ngrok.com/docs/ai-gateway/providers/google
Use Google Gemini Chat Completions, GenerateContent, and Interactions through the ngrok AI Gateway.
[Google AI Studio](https://aistudio.google.com) provides Gemini models.
The gateway supports three APIs:
* OpenAI-compatible Chat Completions: if your OpenAI client already uses the gateway URL and your ngrok access key, change only the model name and send requests to `/v1/chat/completions`.
* Native Gemini GenerateContent: send requests to `/v1beta/models/{model}:generateContent` or `:streamGenerateContent` with a Gemini client.
* Native Gemini Interactions: send stateless create requests to `/v1beta/interactions`, with a JSON response or a stream of server-sent events (SSE).
The OpenAI Responses API (`/v1/responses`) doesn't reach Google models.
Google is a **built-in provider** you can pay for with credits, so a provider key is optional.
Add your own Google key to bill usage to your Google account instead of your ngrok.ai credits.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key and purchase [credits](/docs/ai-gateway/concepts/credits) in [app.ngrok.ai](https://app.ngrok.ai).
Skip this step to pay with credits.
To bring your own key, generate one at [aistudio.google.com](https://aistudio.google.com), then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key).
[Create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with a `google` routing rule and allow Google in the access scope.
To use your own Google key, set the routing rule to **Bring your own API key** and select your stored Google key.
Assign the configuration to your access key.
Follow the [Google Gen AI SDK guide](/docs/ai-gateway/sdks/google) to install the SDK and send requests.
## Native Gemini credentials
See [SDK authentication](/docs/ai-gateway/sdks/google#authentication) for access key headers and credential precedence.
## Generate content requests
See [GenerateContent requests](/docs/ai-gateway/sdks/google#generate-content-requests) for native endpoints and cURL examples, or [SDK streaming](/docs/ai-gateway/sdks/google#streaming) for Python and TypeScript examples.
## Interactions requests
See [SDK Interactions](/docs/ai-gateway/sdks/google#interactions) for examples and gateway restrictions, or [Interactions requests](/docs/ai-gateway/sdks/google#interactions-requests) for the REST endpoint.
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#google).
## Next steps
* [Google Gen AI SDK](/docs/ai-gateway/sdks/google)
* [Provider keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations)
# Groq
Source: https://ngrok.com/docs/ai-gateway/providers/groq
Use Groq LPU-accelerated models through the ngrok AI Gateway.
[Groq](https://groq.com) provides high-speed inference for open-source models (GPT-OSS, Llama 4, Qwen3, and others) using their custom LPU hardware.
Even though Groq is a **built-in provider**, it still requires you to **bring your own key** because you can't pay for it with credits at this time.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key in [app.ngrok.ai](https://app.ngrok.ai).
Sign up at [console.groq.com](https://console.groq.com) and create an API key. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key).
[Create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with a `groq` routing rule and allow Groq in the access scope.
Assign the configuration to your access key and send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="groq:openai/gpt-oss-120b",
messages=[{"role": "user", "content": "Hello!"}]
)
```
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#groq).
## Next steps
* [Provider Keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations)
# Hyperbolic
Source: https://ngrok.com/docs/ai-gateway/providers/hyperbolic
Use Hyperbolic open-source models through the ngrok AI Gateway.
[Hyperbolic](https://hyperbolic.xyz) provides high-performance inference for open-source models.
Even though Hyperbolic is a **built-in provider**, it still requires you to **bring your own key** because you can't pay for it with credits at this time.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key in [app.ngrok.ai](https://app.ngrok.ai).
Sign up at [app.hyperbolic.xyz](https://app.hyperbolic.xyz) and generate an API key. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key).
[Create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with a `hyperbolic` routing rule and allow Hyperbolic in the access scope.
Assign the configuration to your access key and send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="hyperbolic:meta-llama/Llama-3.3-70B-Instruct",
messages=[{"role": "user", "content": "Hello!"}]
)
```
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#hyperbolic).
## Next steps
* [Provider Keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations)
# InceptionLabs
Source: https://ngrok.com/docs/ai-gateway/providers/inceptionlabs
Use InceptionLabs diffusion language models through the ngrok AI Gateway.
[InceptionLabs](https://www.inceptionlabs.ai) develops diffusion-based language models for fast, efficient text generation.
Even though InceptionLabs is a **built-in provider**, it still requires you to **bring your own key** because you can't pay for it with credits at this time.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key in [app.ngrok.ai](https://app.ngrok.ai).
Sign up at [inceptionlabs.ai](https://www.inceptionlabs.ai) and obtain an API key. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key).
[Create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with an `inceptionlabs` routing rule and allow InceptionLabs in the access scope.
Assign the configuration to your access key and send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="inceptionlabs:mercury-coder-small-beta",
messages=[{"role": "user", "content": "Hello!"}]
)
```
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#inceptionlabs).
## Next steps
* [Provider Keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations)
# Inference.net
Source: https://ngrok.com/docs/ai-gateway/providers/inference-net
Use Inference.net distributed inference through the ngrok AI Gateway.
[Inference.net](https://inference.net) provides a distributed inference network for running AI models at scale.
Even though Inference.net is a **built-in provider**, it still requires you to **bring your own key** because you can't pay for it with credits at this time.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key in [app.ngrok.ai](https://app.ngrok.ai).
Sign up at [inference.net](https://inference.net) and generate an API key. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key).
[Create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with an `inference.net` routing rule and allow Inference.net in the access scope.
Assign the configuration to your access key and send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="inference.net:meta-llama/llama-3.1-8b-instruct/fp-8",
messages=[{"role": "user", "content": "Hello!"}]
)
```
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#inference-net).
## Next steps
* [Provider Keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations)
# MiniMax
Source: https://ngrok.com/docs/ai-gateway/providers/minimax
Use MiniMax M-series models through the ngrok AI Gateway.
[MiniMax](https://www.minimax.io) builds the MiniMax M-series models.
MiniMax supports Chat Completions, Responses, and Anthropic Messages requests.
MiniMax is a **built-in provider** you can pay for with credits, so a provider key is optional.
Add your own MiniMax key to bill usage to your MiniMax account instead of your ngrok.ai credits.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key and purchase [credits](/docs/ai-gateway/concepts/credits) in [app.ngrok.ai](https://app.ngrok.ai).
Skip this step to pay with credits.
To bring your own key, create an API key in your [MiniMax](https://www.minimax.io) account. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) and [create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with a `minimax` routing rule that uses it.
Send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="minimax:minimax-m3",
messages=[{"role": "user", "content": "Hello!"}]
)
```
Tencent TokenHub also serves MiniMax M3, so the `minimax:` prefix keeps the request on MiniMax.
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#minimax).
Each `-highspeed` model is a separate model ID, not an option on the base model.
## Next steps
* [Provider keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations)
# Mistral AI
Source: https://ngrok.com/docs/ai-gateway/providers/mistral
Use Mistral AI models through the ngrok AI Gateway.
[Mistral AI](https://mistral.ai) serves its own models and open models from other labs through its API.
Mistral AI supports Chat Completions requests.
Even though Mistral AI is a **built-in provider**, it still requires you to **bring your own key** because you can't pay for it with credits at this time.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key in [app.ngrok.ai](https://app.ngrok.ai).
Create an API key in your [Mistral AI](https://mistral.ai) account. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key).
[Create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with a `mistral` routing rule and allow Mistral AI in the access scope.
Assign the configuration to your access key and send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="mistral:z-ai/glm-5.3",
messages=[{"role": "user", "content": "Hello!"}]
)
```
Other providers also serve GLM-5.3, so the `mistral:` prefix keeps the request on Mistral AI.
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#mistral-ai).
To call a Mistral AI model that isn't in the catalog yet, send its ID with the `mistral:` prefix. See [catalog updates](/docs/ai-gateway/reference/model-catalog#catalog-updates).
## Next steps
* [Provider keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations)
# Moonshot AI
Source: https://ngrok.com/docs/ai-gateway/providers/moonshotai
Use Moonshot AI Kimi models through the ngrok AI Gateway.
[Moonshot AI](https://www.moonshot.ai) builds the Kimi family of models.
Moonshot AI supports Chat Completions requests.
Moonshot AI is a **built-in provider** you can pay for with credits, so a provider key is optional.
Add your own Moonshot AI key to bill usage to your Moonshot AI account instead of your ngrok.ai credits.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key and purchase [credits](/docs/ai-gateway/concepts/credits) in [app.ngrok.ai](https://app.ngrok.ai).
Skip this step to pay with credits.
To bring your own key, create an API key in your [Moonshot AI](https://www.moonshot.ai) account. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) and [create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with a `moonshotai` routing rule that uses it.
Send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="moonshotai:kimi-k3",
messages=[{"role": "user", "content": "Hello!"}]
)
```
QwenCloud and Tencent TokenHub also serve Kimi models, so the `moonshotai:` prefix keeps the request on Moonshot AI.
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#moonshot-ai).
## Next steps
* [Provider keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations)
# OpenAI
Source: https://ngrok.com/docs/ai-gateway/providers/openai
Use OpenAI models through the ngrok AI Gateway.
This guide walks through using [OpenAI](https://openai.com) models with the AI Gateway. OpenAI is a **built-in provider** you can pay for with credits, so you can use OpenAI models without an OpenAI account of your own, or bring your own key.
## Pay with credits (no OpenAI account)
You can use OpenAI models without your own OpenAI account. ngrok.ai supplies the OpenAI credentials and bills the model cost to your credits.
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an [access key](/docs/ai-gateway/concepts/access-keys) and purchase [credits](/docs/ai-gateway/concepts/credits) in [app.ngrok.ai](https://app.ngrok.ai).
Point your SDK at the gateway with your access key:
```python Python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Access key
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
```
```bash cURL theme={null}
curl https://gateway.ngrok.ai/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ng-xxxxx-g1-xxxxx" \
-d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Hello!"}]}'
```
## Bring your own OpenAI key
Want requests billed to your own OpenAI account instead of through credits? Store your OpenAI key once—the gateway attaches it for you on every request.
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an [access key](/docs/ai-gateway/concepts/access-keys) in [app.ngrok.ai](https://app.ngrok.ai) if you don't have one yet.
[Add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) for OpenAI. ngrok stores it encrypted, so it never has to live in your application or get shared around—and you can reuse it across as many access keys as you need.
[Create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with an OpenAI routing rule set to **Bring your own API key**, then assign it to your access key.
Your code doesn't change. Send the same access key as before—the gateway swaps in your OpenAI key before the request leaves for OpenAI.
## Explicit provider routing
```python theme={null}
response = client.chat.completions.create(
model="openai:gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
```
## Available models
Browse the [model catalog](/docs/ai-gateway/reference/model-catalog#openai) for the full list of OpenAI models you can call through the gateway.
## Files and decisions
OpenAI also supports the [Files API](/docs/ai-gateway/guides/files) for uploading documents and images once, and the [Decisions API](/docs/ai-gateway/guides/decisions-and-system-one) for typed answers to questions about your input.
## Next steps
* [Access Keys](/docs/ai-gateway/concepts/access-keys)
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations)
* [Provider Keys](/docs/ai-gateway/guides/attaching-provider-keys)
# OpenRouter
Source: https://ngrok.com/docs/ai-gateway/providers/openrouter
Use OpenRouter models through the ngrok AI Gateway.
[OpenRouter](https://openrouter.ai) is a unified API that provides access to hundreds of models from providers like Anthropic, Google, Meta, Mistral, and more through a single endpoint.
Even though OpenRouter is a **built-in provider**, it still requires you to **bring your own key** because you can't pay for it with credits at this time.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key in [app.ngrok.ai](https://app.ngrok.ai).
Create an account at [openrouter.ai](https://openrouter.ai) and generate an API key from your dashboard. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key).
[Create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with an `openrouter` routing rule and allow OpenRouter in the access scope.
Assign the configuration to your access key and send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="openrouter:anthropic/claude-3.5-sonnet",
messages=[{"role": "user", "content": "Hello!"}]
)
```
## Model names
Always prefix OpenRouter model IDs with `openrouter:`. Without the prefix, the gateway may route to the native provider instead of OpenRouter.
OpenRouter uses a `provider/model` format for its model IDs. When calling through the ngrok AI Gateway, prefix with `openrouter:`:
| What you want | Model string to use |
| - | - |
| Anthropic Claude via OpenRouter | `openrouter:anthropic/claude-3.5-sonnet` |
| Google Gemini via OpenRouter | `openrouter:google/gemini-2.0-flash-001` |
| Meta Llama via OpenRouter | `openrouter:meta-llama/llama-3.1-8b-instruct` |
| Mistral via OpenRouter | `openrouter:mistralai/mistral-7b-instruct` |
The `openrouter:` prefix tells the gateway to route to OpenRouter specifically. Without it, a slash-separated ID such as `anthropic/claude-sonnet-4-6` resolves to the native catalog model, and the gateway sends it to the native provider first.
For the full list of models OpenRouter supports, see [openrouter.ai/models](https://openrouter.ai/models).
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#openrouter).
## Next steps
* [Provider Keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access Key Configurations](/docs/ai-gateway/guides/access-key-configurations)
* [Multi-provider failover](/docs/ai-gateway/examples/multi-provider-failover): failover patterns
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): model IDs and provider prefixes
# QwenCloud
Source: https://ngrok.com/docs/ai-gateway/providers/qwencloud
Use Qwen and other open models from QwenCloud through the ngrok AI Gateway.
[QwenCloud](https://qwencloud.com) serves the Qwen family of models, plus open models from DeepSeek, Moonshot AI, and Z.ai.
QwenCloud supports Chat Completions, Responses, and Anthropic Messages requests.
QwenCloud is a **built-in provider** you can pay for with credits, so a provider key is optional.
Add your own QwenCloud key to bill usage to your QwenCloud account instead of your ngrok.ai credits.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key and purchase [credits](/docs/ai-gateway/concepts/credits) in [app.ngrok.ai](https://app.ngrok.ai).
Skip this step to pay with credits.
To bring your own key, create an API key in your [QwenCloud](https://qwencloud.com) account. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) and [create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with a `qwencloud` routing rule that uses it.
Send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="qwencloud:qwen/qwen3.8-max",
messages=[{"role": "user", "content": "Hello!"}]
)
```
For a model that other providers also serve, such as `moonshotai/kimi-k3`, add the `qwencloud:` prefix to keep the request on QwenCloud.
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#qwencloud).
## Next steps
* [Provider keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations)
# Tencent TokenHub
Source: https://ngrok.com/docs/ai-gateway/providers/tokenhub
Use Hunyuan, GLM, Kimi, DeepSeek, and MiniMax models from Tencent TokenHub through the ngrok AI Gateway.
[Tencent TokenHub](https://www.tencentcloud.com/document/product/1300) serves models from several labs under one API key, including Tencent Hunyuan, Z.ai GLM, Moonshot AI Kimi, DeepSeek, MiniMax, Xiaomi MiMo, and StepFun.
Tencent TokenHub supports Chat Completions, Responses, and Anthropic Messages requests.
Tencent TokenHub is a **built-in provider** you can pay for with credits, so a provider key is optional.
Add your own TokenHub key to bill usage to your Tencent Cloud account instead of your ngrok.ai credits.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key and purchase [credits](/docs/ai-gateway/concepts/credits) in [app.ngrok.ai](https://app.ngrok.ai).
Skip this step to pay with credits.
To bring your own key, create a TokenHub API key in your [Tencent Cloud](https://www.tencentcloud.com/document/product/1300) account. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) and [create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with a `tokenhub` routing rule that uses it.
Send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="tokenhub:tencent/hy3",
messages=[{"role": "user", "content": "Hello!"}]
)
```
Many TokenHub models are also served by their own labs. Add the `tokenhub:` prefix, as in `tokenhub:moonshotai/kimi-k3`, to keep the request on TokenHub.
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#tencent-tokenhub).
## Next steps
* [Provider keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations)
# Typesafe AI
Source: https://ngrok.com/docs/ai-gateway/providers/typesafeai
Use Typesafe AI System One models through the ngrok AI Gateway.
[Typesafe AI](https://typesafe.ai) serves System One models.
Instead of a chat conversation, a System One request sends a `state` and a set of typed `questions`. The response returns a typed answer for each question, with a calibrated probability.
Typesafe AI only supports System One requests at `https://gateway.ngrok.ai/v1/systemone`. Chat Completions, Responses, and Messages requests don't reach Typesafe AI models.
Typesafe AI is a **built-in provider** you can pay for with credits, so a provider key is optional.
Add your own Typesafe AI key to bill usage to your Typesafe AI account instead of your ngrok.ai credits.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key and purchase [credits](/docs/ai-gateway/concepts/credits) in [app.ngrok.ai](https://app.ngrok.ai).
Skip this step to pay with credits.
To bring your own key, create an API key in your [Typesafe AI](https://typesafe.ai) account. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) and [create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with a `typesafeai` routing rule that uses it.
Send a `POST` request to `/v1/systemone` with your access key:
```bash theme={null}
curl https://gateway.ngrok.ai/v1/systemone \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ng-xxxxx-g1-xxxxx" \
-d '{
"model": "jev-latest",
"state": "Customer: My order arrived broken and I want a refund today.",
"questions": {
"urgency": {
"type": "score",
"instructions": "How urgent is this message?",
"criteria": [
"Not urgent: no action needed.",
"Somewhat urgent: handle within a few days.",
"Urgent: handle today."
]
}
}
}'
```
## Request format
A System One request body has three fields:
| Field | Description |
| - | - |
| `model` | The model ID, such as `jev-latest`. |
| `state` | The text the model evaluates. |
| `questions` | An object that maps each question ID to a typed question. It must contain at least one question. |
The gateway removes any other top-level field before it forwards the request.
System One doesn't stream, so a request with `"stream": true` returns an error.
See the [Typesafe AI API reference](https://docs.typesafe.ai) for question types and the response format.
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#typesafe-ai). `jev-latest` points at the current Jev build, and `jev-preview` points at the next one.
## Next steps
* [Typed-question APIs](/docs/ai-gateway/guides/decisions-and-system-one): How System One requests work
* [Provider keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations)
# xAI
Source: https://ngrok.com/docs/ai-gateway/providers/xai
Use xAI Grok models through the ngrok AI Gateway.
[xAI](https://x.ai) builds the Grok family of models.
xAI supports Chat Completions and Responses requests.
Responses requests to xAI aren't stored, so `previous_response_id` isn't available. Send the full conversation in each request.
xAI is a **built-in provider** you can pay for with credits, so a provider key is optional.
Add your own xAI key to bill usage to your xAI account instead of your ngrok.ai credits.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key and purchase [credits](/docs/ai-gateway/concepts/credits) in [app.ngrok.ai](https://app.ngrok.ai).
Skip this step to pay with credits.
To bring your own key, create an API key in your [xAI](https://x.ai) account. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) and [create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with an `xai` routing rule that uses it.
Send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="grok-4.7",
messages=[{"role": "user", "content": "Hello!"}]
)
```
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#xai).
## Next steps
* [Provider keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations)
# Z.ai
Source: https://ngrok.com/docs/ai-gateway/providers/z-ai
Use Z.ai GLM models through the ngrok AI Gateway.
[Z.ai](https://z.ai/model-api), formerly Zhipu AI, builds the open-weight GLM family of models for agents, reasoning, and coding.
Z.ai supports Chat Completions requests.
Z.ai is a **built-in provider** you can pay for with credits, so a provider key is optional.
Add your own Z.ai key to bill usage to your Z.ai account instead of your ngrok.ai credits.
## Setup
Follow the [quickstart](/docs/ai-gateway/quickstart) to create an access key and purchase [credits](/docs/ai-gateway/concepts/credits) in [app.ngrok.ai](https://app.ngrok.ai).
Skip this step to pay with credits.
To bring your own key, create an API key in your [Z.ai](https://z.ai/model-api) account. Then [add a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key) and [create an access key configuration](/docs/ai-gateway/guides/access-key-configurations#create-a-configuration) with a `z-ai` routing rule that uses it.
Send requests with your access key:
```python theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx",
)
response = client.chat.completions.create(
model="z-ai:glm-5.3",
messages=[{"role": "user", "content": "Hello!"}]
)
```
QwenCloud, Tencent TokenHub, and Mistral AI also serve GLM models, so the `z-ai:` prefix keeps the request on Z.ai.
## Available models
See the [model catalog](/docs/ai-gateway/reference/model-catalog#z-ai).
## Next steps
* [Provider keys](/docs/ai-gateway/guides/attaching-provider-keys)
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations)
# Quickstart
Source: https://ngrok.com/docs/ai-gateway/quickstart
Integrate ngrok.ai with your application in minutes.
The onboarding should have you covered, but this short quickstart guide is here just in case.
## Making your first request
Open [app.ngrok.ai](https://app.ngrok.ai) and sign in with your ngrok account.
[Top-up at least \$5.00](https://app.ngrok.ai/billing). Every request you make requires [ngrok.ai credits](/docs/ai-gateway/concepts/credits).
Open [Access Keys](https://app.ngrok.ai/keys) and create a new key. Copy the key right away—it's shown only once—and store it somewhere safe. It looks like `ng-xxxxx-g1-xxxxx`.
Point your OpenAI SDK at the gateway using your access key:
```js highlight={4,5} theme={null}
import OpenAI from "openai";
const openai = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx"
});
const res = await openai.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Hello, world!" }]
});
```
No need to sign up to OpenAI or bring your own keys for this request. ngrok.ai will handle the billing for you.
## Already have credits and an access key?
Complete the ngrok AI Gateway SDK integration (I've already signed up on app.ngrok.ai, purchased credits, and have an access key):
1. Ask me for my access key (format: ng-xxxxx-g1-xxxxx). The gateway URL is always [https://gateway.ngrok.ai](https://gateway.ngrok.ai)
2. Install the OpenAI SDK: `npm install openai` or `pip install openai`
3. Write a script that routes OpenAI SDK requests through the gateway by setting baseURL to [https://gateway.ngrok.ai/v1](https://gateway.ngrok.ai/v1) and apiKey to my ng-xxxxx key
4. Send a test request with model `gpt-4o` and message "State your exact model name and provider."
5. Print and verify the response
Ask me for my access key before writing any code.
## Next steps
* [Access keys](/docs/ai-gateway/concepts/access-keys): Understand how keys work and manage them
* [Credits](/docs/ai-gateway/concepts/credits): How usage is billed
* [SDK Integration](/docs/ai-gateway/sdks): Connect with OpenAI, Anthropic, and other SDKs
* [Bring Your Own Keys](/docs/ai-gateway/concepts/bring-your-own-keys): Use your own provider API keys for more providers
* [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself): Connect Ollama, vLLM, LM Studio, or another private model.
# Error Codes Reference
Source: https://ngrok.com/docs/ai-gateway/reference/error-codes
When the AI Gateway encounters an error, it returns an ngrok error code and message to help identify the issue. The full list of AI Gateway error codes and their meanings are listed on this page.
These errors apply to requests sent to `https://gateway.ngrok.ai` with an [access key](/docs/ai-gateway/concepts/access-keys).
Every response carries the request's ID in `Ngrok-AIG-Request-Id`, so quote that value when you contact support.
See [Response headers](/docs/ai-gateway/how-it-works#response-headers).
## Request and routing errors
The gateway rejects these before it makes any upstream attempt, so the response carries no `Ngrok-AIG-Attempts` header and the request is not billed.
### ERR\_NGROK\_27228
**Message**
Invalid request: `REASON`
**HTTP Status**
400 Bad Request
**Causes**
* The request body is not valid JSON
* A required field is missing for the API surface you called
* A field holds a value the surface does not accept
**Solutions**
* Check the reason in the message for the offending field
* Verify the body matches the API surface you posted to, whether Chat Completions, Responses, Messages, or the native Gemini surface
***
### ERR\_NGROK\_27224
**Message**
Unknown model "`MODELID`".`SUGGESTION`
**HTTP Status**
400 Bad Request
**Causes**
* The model ID is misspelled
* The model is not in the [model catalog](/docs/ai-gateway/reference/model-catalog) and no custom provider defines it
**Solutions**
* Check the suggestion in the message, which names the closest catalog match
* Look the model up in the [model catalog](/docs/ai-gateway/reference/model-catalog)
* Qualify the model with its provider, such as `openai:gpt-4o`. See [Choose a model](/docs/ai-gateway/guides/model-selection-strategies)
***
### ERR\_NGROK\_27225
**Message**
Unknown provider "`PROVIDERID`".
**HTTP Status**
400 Bad Request
**Causes**
* The provider prefix is misspelled
* The provider is a custom provider that does not exist on your account
**Solutions**
* List your providers with the [Providers API](/docs/ai-gateway/api-reference/providers/list)
* [Register the custom provider](/docs/ai-gateway/concepts/custom-providers) before routing to it
***
### ERR\_NGROK\_27230
**Message**
"`MODEL`" is not a known model, and "`PROVIDER`" is not a recognized provider.
**HTTP Status**
400 Bad Request
**Causes**
* A provider-qualified model name whose prefix is neither a known provider nor part of a real model ID
**Solutions**
* Use `provider:model`, with the provider exactly as the [Providers API](/docs/ai-gateway/api-reference/providers/list) reports it
* Drop the prefix to let the gateway resolve the model from the catalog
***
### ERR\_NGROK\_27229
**Message**
Invalid model address "`ADDRESS`".
**HTTP Status**
400 Bad Request
**Causes**
* The model field is empty, or holds more separators than `provider:model` allows
**Solutions**
* Send either a bare model ID or a single `provider:model` pair
***
### ERR\_NGROK\_27204
**Message**
Unsupported API surface "`PATH`".
**HTTP Status**
400 Bad Request
**Causes**
* The request path is not one the gateway serves
**Solutions**
* Post to `/v1/chat/completions`, `/v1/responses`, `/v1/messages`, `/v1/decisions`, `/v1/systemone`, `/v1/files`, the native Gemini path `/v1beta/models/{model}:generateContent`, or `/v1beta/interactions`
* The gateway does not serve `/v1/embeddings`, `/v1/completions`, or image and audio endpoints
* Point your SDK's base URL at `https://gateway.ngrok.ai/v1` rather than a full endpoint path
***
### ERR\_NGROK\_27226
**Message**
Provider "`PROVIDERID`" does not support API surface "`SURFACE`".
**HTTP Status**
400 Bad Request
**Causes**
* The provider has no equivalent of the surface you called, such as the Responses API on a provider that only serves Chat Completions
**Solutions**
* Call the surface the provider supports. See the provider's page under [Getting Started With](/docs/ai-gateway/providers/openai)
* Choose a different provider for that surface
***
### ERR\_NGROK\_27205
**Message**
API surface "`SURFACE`" is not implemented.
**HTTP Status**
501 Not Implemented
**Causes**
* The gateway knows this endpoint but doesn't support it yet
**Solutions**
* Use a supported endpoint such as `/v1/chat/completions`. See [ERR\_NGROK\_27204](#err_ngrok_27204) for the full list
***
### ERR\_NGROK\_27250
**Message**
ngrok doesn't store interactions yet, so "store" can't be true. Omit it or set it to false to send a stateless request.
**HTTP Status**
400 Bad Request
**Causes**
* An Interactions API request set `store` to `true`
**Solutions**
* Omit `store`, or set it to `false`. See [Google SDK](/docs/ai-gateway/sdks/google)
***
## Access policy errors
### ERR\_NGROK\_27231
**Message**
Provider "`PROVIDERID`" is not allowed by the access policy.
**HTTP Status**
403 Forbidden
**Causes**
* The access key's configuration does not include the provider in its access scope
**Solutions**
* Allow the provider in the key's [access key configuration](/docs/ai-gateway/guides/access-key-configurations)
* See [Restrict providers and models](/docs/ai-gateway/guides/restrict-providers-and-models) for how scope is evaluated
***
### ERR\_NGROK\_27232
**Message**
Model "`MODELID`" is not allowed by the access policy.
**HTTP Status**
403 Forbidden
**Causes**
* The configuration's access scope excludes the model, even though the provider is allowed
**Solutions**
* Add the model to the access scope in the key's [access key configuration](/docs/ai-gateway/guides/access-key-configurations)
***
## Credential and credit errors
### ERR\_NGROK\_27201
**Message**
Authentication failed: `REASON`
**HTTP Status**
401 Unauthorized
**Causes**
* No access key in the request
* The access key is malformed, revoked, or deleted
**Solutions**
* Send your [access key](/docs/ai-gateway/concepts/access-keys) as `Authorization: Bearer ng-xxxxx-g1-xxxxx`, or as `x-api-key` on the Anthropic surface and `X-Goog-Api-Key` on the native Gemini surface
* Confirm the key still exists with the [Access Keys API](/docs/ai-gateway/api-reference/access-keys/list)
***
### ERR\_NGROK\_27202
**Message**
No keys available for provider "`PROVIDERID`".
**HTTP Status**
502 Bad Gateway
**Causes**
* The access key's configuration has no routing credentials for the requested provider
* Every provider key the configuration referenced was deleted
**Solutions**
* Add a routing rule for the provider in the key's [access key configuration](/docs/ai-gateway/guides/access-key-configurations)
* [Attach a provider key](/docs/ai-gateway/guides/attaching-provider-keys#add-a-provider-key), or [pay with credits](/docs/ai-gateway/guides/pay-with-credits) where the provider supports it
***
### ERR\_NGROK\_27206
**Message**
Credit check failed: `REASON`
**HTTP Status**
402 Payment Required
**Causes**
* The account's credit balance is zero or below, or billing is not set up for the account yet
* Every request needs credits, even with your own provider keys, because each one pays a small processing fee
**Solutions**
* Check your balance with the [Credits API](/docs/ai-gateway/api-reference/credits/balance)
* [Purchase credits](https://app.ngrok.ai/billing). Your own provider key does not bypass this check
***
### ERR\_NGROK\_27233
**Message**
Model "`MODELID`" is not available with an ngrok-managed key for provider "`PROVIDERID`": add your own provider key to use uncataloged models.
**HTTP Status**
400 Bad Request
**Causes**
* The model isn't in the ngrok.ai catalog, so ngrok.ai has no price for it
**Solutions**
* [Attach your own provider key](/docs/ai-gateway/guides/attaching-provider-keys) for that provider
* Pick a catalog model instead. See the [model catalog](/docs/ai-gateway/reference/model-catalog)
***
### ERR\_NGROK\_27239
**Message**
ngrok can't serve "`MODELID`" on provider "`PROVIDERID`" with an ngrok-managed key right now. Add your own provider key to use it.
**HTTP Status**
503 Service Unavailable
**Causes**
* You can't pay for this model with credits on that provider right now
**Solutions**
* Retry, or fail over to another model. See [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models)
* [Attach your own provider key](/docs/ai-gateway/guides/attaching-provider-keys) for that provider
***
### ERR\_NGROK\_27236
**Message**
Model "`MODELID`" is not priced for managed billing yet for provider "`PROVIDERID`"; add your own provider key to use it.
**HTTP Status**
400 Bad Request
**Causes**
* You can't pay for this model with credits on that provider yet, because ngrok.ai doesn't have a price for it
**Solutions**
* [Attach your own provider key](/docs/ai-gateway/guides/attaching-provider-keys) for that provider
* Pick another model from the [model catalog](/docs/ai-gateway/reference/model-catalog)
***
### ERR\_NGROK\_27238
**Message**
An ngrok-managed key can't serve this request, because ngrok can't bill `FEATURE` for "`MODELID`" on provider "`PROVIDERID`". Add your own provider key to use it.
**HTTP Status**
400 Bad Request
**Causes**
* The request uses a feature, such as a hosted tool, that you can't pay for with credits on that model
**Solutions**
* Remove the feature from the request
* [Attach your own provider key](/docs/ai-gateway/guides/attaching-provider-keys) for that provider
***
### ERR\_NGROK\_27249
**Message**
ngrok doesn't offer "`MODELID`" on provider "`PROVIDERID`" with an ngrok-managed key. Add your own provider key to use it.
**HTTP Status**
400 Bad Request
**Causes**
* The model exists in the catalog, but you can't pay for it with credits on that provider
**Solutions**
* [Attach your own provider key](/docs/ai-gateway/guides/attaching-provider-keys) for that provider
* Pick a model you can pay for with credits. See the [model catalog](/docs/ai-gateway/reference/model-catalog#billing-and-provider-credentials)
***
### ERR\_NGROK\_27240
**Message**
Your account has no `FILES` for provider "`PROVIDERID`". An ngrok-managed key can only use files your account uploaded. Upload the file first, or add your own provider key.
**HTTP Status**
404 Not Found
**Causes**
* The request uses a file that wasn't uploaded from your account, so you can't pay for it with credits
**Solutions**
* [Attach your own provider key](/docs/ai-gateway/guides/attaching-provider-keys) to use files stored in your provider account
***
## Upstream failures
These arrive after the gateway tries at least one provider, so `Ngrok-AIG-Attempts` tells you how many tries the gateway made.
See [Handle gateway errors](/docs/ai-gateway/guides/error-handling) for the order it tries them in.
When every model fails, or the request hits the 10-attempt cap, the gateway returns the last model's error.
### ERR\_NGROK\_27211
**Message**
Upstream provider rejected the API key.
**HTTP Status**
401 Unauthorized
**Causes**
* The provider key stored in ngrok is invalid, revoked, or rotated at the provider
**Solutions**
* [Rotate the provider key](/docs/ai-gateway/api-reference/provider-keys/rotate) to the current value
* Verify the key directly against the provider
***
### ERR\_NGROK\_27217
**Message**
Upstream provider rate limit exceeded.
**HTTP Status**
429 Too Many Requests
**Causes**
* Every credential and candidate the gateway tried was rate limited
**Solutions**
* Attach more [provider keys](/docs/ai-gateway/guides/attaching-provider-keys) so the gateway has another credential to try
* Add candidates from other providers. See [Multi-provider failover](/docs/ai-gateway/examples/multi-provider-failover)
* Slow your request rate, or raise your quota with the provider
***
### ERR\_NGROK\_27207
**Message**
Upstream request timed out.
**HTTP Status**
504 Gateway Timeout
**Causes**
* A single upstream attempt exceeded the per-request timeout
**Solutions**
* Raise the per-request timeout in [Account Settings](/docs/ai-gateway/guides/account-settings)
* Shorten the prompt, or choose a faster model
***
### ERR\_NGROK\_3810
**Message**
Request timed out after `TIMEOUT`. Try a shorter prompt or increase your timeout.
**HTTP Status**
504 Gateway Timeout
**Causes**
* Every attempt together exceeded the total timeout
* Too many slow candidates in the failover list
**Solutions**
* Raise the total timeout in [Account Settings](/docs/ai-gateway/guides/account-settings)
* Lower the per-request timeout so a slow provider fails sooner and leaves budget for the next candidate
* Reduce the number of failover candidates
***
### ERR\_NGROK\_27227
**Message**
No backend available: `REASON`
**HTTP Status**
502 Bad Gateway
**Causes**
* None of the models in the request could be used, for example because the access key can't reach them
* With `ngrok/auto`, none of the models the key can reach are available for automatic selection. See [Automatic model selection](/docs/ai-gateway/guides/automatic-model-selection)
**Solutions**
* Confirm the configuration's routing rules cover the provider you requested
* See [Handle gateway errors](/docs/ai-gateway/guides/error-handling) for the order the gateway tries models in
***
### ERR\_NGROK\_27237
**Message**
Request rejected: a routing loop was detected. Double check your custom provider URLs do not cause an infinite proxy loop.
**HTTP Status**
502 Bad Gateway
**Causes**
* A custom provider's base URL points back at the AI Gateway
**Solutions**
* Point the custom provider at its real upstream. See [Use a model you run yourself](/docs/ai-gateway/guides/use-a-model-you-run-yourself)
***
## Limit errors
### ERR\_NGROK\_3811
**Message**
Input too large: `INPUTTOKENS` tokens (max `MAXALLOWED`). Shorten your prompt.
**HTTP Status**
413 Payload Too Large
**Causes**
* The prompt and context exceed the account's max input tokens
* Very long conversation history, or large embedded content in messages
**Solutions**
* Reduce the prompt length or conversation history
* Raise or clear `maxInputTokens` in [Account Settings](/docs/ai-gateway/guides/account-settings)
* Count tokens client-side before sending
***
### ERR\_NGROK\_AI\_GATEWAY\_REQUEST\_BODY\_TOO\_LONG
**Message**
Request body is too long. Max 32 MiB.
**HTTP Status**
413 Payload Too Large
**Causes**
* The request body is larger than 32 MiB
**Solutions**
* Upload large documents and images with the [Files API](/docs/ai-gateway/guides/files) instead of sending them inline
* Reduce the conversation history or embedded content
***
## Retired setup
### ERR\_NGROK\_3820
**Message**
```text theme={null}
AI Gateway has a new home at https://app.ngrok.ai. The old ai-gateway traffic
policy action has been retired. Existing credits have been migrated to
https://app.ngrok.ai. If you have any questions or issues, please reach out to
support@ngrok.com.
```
**HTTP Status**
403 Forbidden
**Causes**
* A Traffic Policy still contains the retired `ai-gateway` action
**Solutions**
* Remove the `ai-gateway` action from the endpoint's Traffic Policy
* Send LLM traffic to `https://gateway.ngrok.ai` with an [access key](/docs/ai-gateway/concepts/access-keys) instead, and manage the gateway at [app.ngrok.ai](https://app.ngrok.ai)
* Credits from the retired setup were migrated automatically. Email [support@ngrok.com](mailto:support@ngrok.com) if your balance looks wrong
***
## Other codes
The gateway returns one code per upstream status class, beyond the ones above.
Each has a page under [ngrok error codes](/docs/errors):
| Code | Meaning |
| - | - |
| `ERR_NGROK_27210` | Upstream provider rejected the request |
| `ERR_NGROK_27212` | Upstream provider denied access |
| `ERR_NGROK_27213` | Upstream provider returned not found |
| `ERR_NGROK_27214` | Upstream provider request timed out |
| `ERR_NGROK_27215` | Request payload exceeded upstream provider limits |
| `ERR_NGROK_27216` | Upstream provider could not process the request |
| `ERR_NGROK_27218` | Upstream provider returned an internal server error |
| `ERR_NGROK_27219` | Upstream provider returned a bad gateway error |
| `ERR_NGROK_27220` | Upstream provider is unavailable |
| `ERR_NGROK_27221` | Upstream provider gateway timed out |
| `ERR_NGROK_27222` | Upstream provider returned an unexpected status |
| `ERR_NGROK_27234` | Upstream returned a non-streaming response to a streaming request |
| `ERR_NGROK_27235` | Upstream provider failed to respond, for example a dropped connection |
| `ERR_NGROK_27241` to `ERR_NGROK_27248` | Files API errors. See [Upload and use files](/docs/ai-gateway/guides/files#errors) |
## SDK error handling
Handle ngrok errors in your SDK:
```python OpenAI Python SDK theme={null}
from openai import OpenAI, APIError
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx"
)
try:
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}]
)
except APIError as e:
print(f"Error code: {e.code}")
print(f"Message: {e.message}")
if "ERR_NGROK_27224" in str(e):
print("Model not found - check model name spelling")
```
```javascript OpenAI Node.js SDK theme={null}
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://gateway.ngrok.ai/v1',
apiKey: 'ng-xxxxx-g1-xxxxx',
});
try {
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
});
} catch (error) {
if (error instanceof OpenAI.APIError) {
console.log('Status:', error.status);
console.log('Message:', error.message);
if (error.message.includes('ERR_NGROK_27224')) {
console.log('Model not found - check model name spelling');
}
}
}
```
## Next steps
Diagnose a failure from the response
Which failures the gateway retries, and in what order
# Model Catalog
Source: https://ngrok.com/docs/ai-gateway/reference/model-catalog
Built-in providers and models available on ngrok.ai.
ngrok.ai maintains a catalog of known providers and models. This catalog enables automatic model resolution, routing, model validation, and rich metadata for selection strategies.
## How the catalog works
When you send a request with a model name like `gpt-4o`, the gateway automatically:
1. Resolves the model using the catalog
2. Finds every provider that serves the model, with the model author's own provider (for example, OpenAI) first, and applies the right provider credentials
3. Routes the request to the provider’s endpoint
If you want to explicitly select a provider, use the `provider:model` format in the model string. For example:
```json theme={null}
{
"model": "openai:gpt-4o",
"messages": [{"role": "user", "content": "Hello"}]
}
```
## Built-in providers
The catalog includes built-in providers—public AI APIs with known models and routing metadata. You can manage them on the [Providers page](https://app.ngrok.ai/providers).
### Authentication
Send traffic using an [access key](/docs/ai-gateway/concepts/access-keys). This key authenticates your requests to the gateway, not to the upstream provider.
### Billing and provider credentials
The AI Gateway splits billing into two parts: using the gateway and paying the model provider.
Many built-in models don’t need a provider key. You can spot them in the tables below: if **Needs BYOK?** says “No,” you can use the model right away as long as you have credits. The gateway takes care of authentication and charges your credits. Availability is per model, so a provider can have some models you can pay for with credits and some you can't.
Other providers do need a key. For those, add your provider key in app.ngrok.ai. The provider will bill you directly for model usage, and your credits will cover the gateway fee. This is often called BYOK (bring your own key).
### OpenAI
| Field | Value |
| - | - |
| **Provider ID** | `openai` |
| **Base URL** | `https://api.openai.com/v1/` |
| **Website** | [openai.com](https://openai.com/) |
| **API surfaces** | Responses, Chat Completions, Decisions |
| **Provider key required** | No |
[How to use OpenAI →](/docs/ai-gateway/providers/openai)
#### OpenAI models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `gpt-6.1-sol` | 1M | 128K | Text Image | No |
| `gpt-6-luna` | 1M | 128K | Text Image | No |
| `gpt-6-sol` | 1M | 128K | Text Image | No |
| `gpt-6-astra` | 1M | 128K | Text Image | No |
| `gpt-5.6-luna` | 1M | 128K | Text Image | No |
| `gpt-5.6-sol` | 1M | 128K | Text Image | No |
| `gpt-5.6-terra` | 1M | 128K | Text Image | No |
| `gpt-5.5` | 1M | 128K | Text Image | No |
| `gpt-5.5-pro` | 1M | 128K | Text Image | No |
| `gpt-5.4-mini` | 400K | 128K | Text Image | No |
| `gpt-5.4-nano` | 400K | 128K | Text Image | No |
| `gpt-5.4` | 1M | 128K | Text Image | No |
| `gpt-5.4-pro` | 1M | 128K | Text Image | No |
| `gpt-5.3-codex` | 400K | 128K | Text Image | No |
| `gpt-5.2-codex` | 400K | 128K | Text Image | No |
| `gpt-5.2` | 400K | 128K | Text Image | No |
| `gpt-5.2-chat-latest` | 128K | 16K | Text Image | No |
| `gpt-5.2-pro` | 400K | 128K | Text Image | No |
| `gpt-5.1-chat-latest` | 128K | 16K | Text Image | No |
| `gpt-5.1` | 400K | 128K | Text Image | No |
| `gpt-5-pro` | 400K | 272K | Text Image | No |
| `gpt-5` | 400K | 128K | Text Image | No |
| `gpt-5-chat-latest` | 128K | 16K | Text Image | No |
| `gpt-5-mini` | 400K | 128K | Text Image | No |
| `gpt-5-nano` | 400K | 128K | Text Image | No |
| `o3-deep-research` | 200K | 100K | Text Image | No |
| `o4-mini-deep-research` | 200K | 100K | Text Image | No |
| `o3-pro` | 200K | 100K | Text Image | No |
| `o3` | 200K | 100K | Text Image | No |
| `o4-mini` | 200K | 100K | Text Image | No |
| `gpt-4.1` | 1M | 32K | Text Image | No |
| `gpt-4.1-mini` | 1M | 32K | Text Image | No |
| `gpt-4.1-nano` | 1M | 32K | Text Image | No |
| `o1-pro` | 200K | 100K | Text Image | No |
| `o3-mini` | 200K | 100K | Text | No |
| `o1` | 200K | 100K | Text Image | No |
| `gpt-4o-mini` | 128K | 16K | Text Image | No |
| `gpt-4o` | 128K | 16K | Text Image | No |
| `gpt-4-turbo` | 128K | 4K | Text Image | No |
| `gpt-4` | 8K | 8K | Text | No |
| `gpt-3.5-turbo` | 16K | 4K | Text | No |
***
### Anthropic
| Field | Value |
| - | - |
| **Provider ID** | `anthropic` |
| **Base URL** | `https://api.anthropic.com/v1/` |
| **Website** | [anthropic.com](https://anthropic.com/) |
| **API surfaces** | Chat Completions, Messages |
| **Provider key required** | No |
[How to use Anthropic →](/docs/ai-gateway/providers/anthropic)
#### Anthropic models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `claude-haiku-5-5` | 1M | 128K | Text Image File | No |
| `claude-sonnet-5-5` | 1M | 128K | Text Image File | No |
| `claude-opus-5-5` | 1M | 128K | Text Image File | No |
| `claude-fable-5-1` | 1M | 128K | Text Image File | No |
| `claude-opus-5` | 1M | 128K | Text Image File | No |
| `claude-sonnet-5` | 1M | 128K | Text Image File | No |
| `claude-fable-5` | 1M | 128K | Text Image File | No |
| `claude-opus-4-8` | 1M | 128K | Text Image File | No |
| `claude-opus-4-7` | 1M | 128K | Text Image File | No |
| `claude-sonnet-4-6` | 1M | 128K | Text Image File | No |
| `claude-opus-4-6` | 1M | 128K | Text Image File | No |
| `claude-opus-4-5` | 200K | 64K | Text Image File | No |
| `claude-haiku-4-5` | 200K | 64K | Text Image File | No |
| `claude-sonnet-4-5` | 200K | 64K | Text Image File | No |
| `claude-opus-4-1` | 200K | 32K | Text Image File | No |
***
### Google
| Field | Value |
| - | - |
| **Provider ID** | `google` |
| **Base URL** | `https://generativelanguage.googleapis.com/v1beta/openai/` |
| **Website** | [aistudio.google.com](https://aistudio.google.com/) |
| **API surfaces** | Chat Completions, Gemini GenerateContent, Interactions |
| **Provider key required** | For some models. See **Needs BYOK?** |
[How to use Google →](/docs/ai-gateway/providers/google)
#### Google models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `gemini-3.8-flash` | 1M | 64K | Text Image Audio Video File | No |
| `gemini-3.7-flash` | 1M | 64K | Text Image Audio Video File | No |
| `gemini-3.5-flash-lite` | 1M | 64K | Text Image Audio Video File | No |
| `gemini-3.6-flash` | 1M | 64K | Text Image Audio Video File | No |
| `gemini-3.5-flash` | 1M | 64K | Text Image Audio Video File | No |
| `gemini-3.1-flash-lite` | 1M | 64K | Text Image Audio Video File | No |
| `gemini-3.1-pro-preview` | 1M | 64K | Text Image Audio Video File | No |
| `gemini-3.1-pro-preview-customtools` | 1M | 64K | Text Image Audio Video File | No |
| `gemini-3-flash-preview` | 1M | 64K | Text Image Audio Video File | No |
| `gemini-2.5-flash-lite` | 1M | 64K | Text Image Audio Video File | Yes |
| `gemini-2.5-flash` | 1M | 64K | Text Image Audio Video File | Yes |
| `gemini-2.5-pro` | 1M | 64K | Text Image Audio Video File | Yes |
Google serves the Gemini 2.5 models only to Google projects created before mid-2026. Newer projects get a 404 stating the model is no longer available to new users. The Google project ngrok.ai uses postdates that cutoff, so these models are reachable only with your own key on an older project.
***
### DeepSeek
| Field | Value |
| - | - |
| **Provider ID** | `deepseek` |
| **Base URL** | `https://api.deepseek.com/v1` |
| **Website** | [deepseek.com](https://www.deepseek.com/) |
| **API surfaces** | Chat Completions, Responses, Messages |
| **Provider key required** | No |
[How to use DeepSeek →](/docs/ai-gateway/providers/deepseek)
#### DeepSeek models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `deepseek-flash` | 1M | 384K | Text | No |
| `deepseek-v4-flash` | 1M | 384K | Text | No |
| `deepseek-v4-pro` | 1M | 384K | Text | No |
***
### xAI
| Field | Value |
| - | - |
| **Provider ID** | `xai` |
| **Base URL** | `https://api.x.ai/v1` |
| **Website** | [x.ai](https://x.ai/) |
| **API surfaces** | Chat Completions, Responses |
| **Provider key required** | No |
[How to use xAI →](/docs/ai-gateway/providers/xai)
#### xAI models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `grok-4.7` | 500K | — | Text Image | No |
| `grok-4.6` | 500K | — | Text Image | No |
| `grok-4.5` | 500K | — | Text Image | No |
| `grok-build-0.1` | 256K | — | Text Image | No |
| `grok-4.3` | 1M | — | Text Image | No |
***
### Groq
| Field | Value |
| - | - |
| **Provider ID** | `groq` |
| **Base URL** | `https://api.groq.com/openai/v1` |
| **Website** | [groq.com](https://groq.com/) |
| **API surfaces** | Chat Completions, Responses |
| **Provider key required** | Yes |
[How to use Groq →](/docs/ai-gateway/providers/groq)
Groq provides AI inference powered by their custom LPU (Language Processing Unit) hardware.
#### Groq models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `openai/gpt-oss-safeguard-20b` | 128K | 64K | Text | Yes |
| `openai/gpt-oss-120b` | 128K | 64K | Text | Yes |
| `openai/gpt-oss-20b` | 128K | 64K | Text | Yes |
| `meta-llama/llama-prompt-guard-2-22m` | 512 | 512 | Text | Yes |
| `meta-llama/llama-prompt-guard-2-86m` | 512 | 512 | Text | Yes |
| `qwen/qwen3-32b` | 128K | 40K | Text | Yes |
| `meta-llama/llama-4-scout-17b-16e-instruct` | 128K | 8K | Text Image | Yes |
***
### Mistral AI
| Field | Value |
| - | - |
| **Provider ID** | `mistral` |
| **Base URL** | `https://api.mistral.ai/v1` |
| **Website** | [mistral.ai](https://mistral.ai) |
| **API surfaces** | Chat Completions |
| **Provider key required** | Yes |
[How to use Mistral AI →](/docs/ai-gateway/providers/mistral)
#### Mistral AI models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `z-ai/glm-5.3` | 1M | 128K | Text | Yes |
***
### Moonshot AI
| Field | Value |
| - | - |
| **Provider ID** | `moonshotai` |
| **Base URL** | `https://api.moonshot.ai/v1` |
| **Website** | [moonshot.ai](https://www.moonshot.ai/) |
| **API surfaces** | Chat Completions |
| **Provider key required** | No |
[How to use Moonshot AI →](/docs/ai-gateway/providers/moonshotai)
#### Moonshot AI models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `kimi-k3` | 1M | 1M | Text Image Video | No |
| `kimi-k2.7-code` | 256K | 256K | Text Image Video | No |
| `kimi-k2.7-code-highspeed` | 256K | 256K | Text Image Video | No |
| `kimi-k2.6` | 256K | 256K | Text Image Video | No |
***
### Z.ai
| Field | Value |
| - | - |
| **Provider ID** | `z-ai` |
| **Base URL** | `https://api.z.ai/api/paas/v4` |
| **Website** | [z.ai/model-api](https://z.ai/model-api) |
| **API surfaces** | Chat Completions |
| **Provider key required** | No |
[How to use Z.ai →](/docs/ai-gateway/providers/z-ai)
#### Z.ai models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `glm-5.3-flash` | 1M | 128K | Text Image Video File | No |
| `glm-5.3` | 1M | 128K | Text | No |
| `glm-5.2` | 1M | 128K | Text | No |
| `glm-5.1` | 200K | 128K | Text | No |
| `glm-5-turbo` | 200K | 128K | Text | No |
| `glm-5` | 200K | 128K | Text | No |
| `glm-4.7-flash` | 200K | 128K | Text | No |
| `glm-4.7-flashx` | 200K | 128K | Text | No |
| `glm-4.7` | 200K | 128K | Text | No |
| `glm-4.6` | 200K | 128K | Text | No |
| `glm-4.5` | 128K | 96K | Text | No |
| `glm-4.5-air` | 128K | 96K | Text | No |
| `glm-4.5-airx` | 128K | 96K | Text | No |
| `glm-4.5-flash` | 128K | 96K | Text | No |
| `glm-4.5-x` | 128K | 96K | Text | No |
| `glm-4-32b-0414-128k` | 128K | 16K | Text | No |
| `glm-5.3-flashx` | 1M | 128K | Text Image Video File | No |
***
### QwenCloud
| Field | Value |
| - | - |
| **Provider ID** | `qwencloud` |
| **Base URL** | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` |
| **Website** | [qwencloud.com](https://qwencloud.com/) |
| **API surfaces** | Chat Completions, Messages, Responses |
| **Provider key required** | No |
[How to use QwenCloud →](/docs/ai-gateway/providers/qwencloud)
#### QwenCloud models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `deepseek/deepseek-flash` | 1M | 384K | Text | No |
| `deepseek/deepseek-v4.1-flash` | 1M | 384K | Text | No |
| `qwen/qwen3.8-max` | 1M | 128K | Text Image Video | No |
| `qwen/qwen3.8-flash` | 1M | 128K | Text Image Video | No |
| `z-ai/glm-5.3` | 1M | 128K | Text | No |
| `qwen/qwen3.8-2.4t-a95b` | 1M | 128K | Text | No |
| `qwen/qwen3.7-flash` | 1M | 128K | Text Image Video | No |
| `moonshotai/kimi-k3` | 1M | 1M | Text Image Video | No |
| `z-ai/glm-5.2` | 1M | 128K | Text | No |
| `z-ai/glm-5.2-fast-preview` | 1M | 128K | Text | No |
| `qwen/qwen3.7-plus` | 1M | 128K | Text Image Video | No |
| `qwen/qwen3.7-max` | 1M | 128K | Text | No |
| `deepseek/deepseek-v4-pro` | 1M | 384K | Text | No |
| `qwen/qwen3.6-plus` | 1M | 64K | Text Image Video | No |
| `qwen/qwen3.5-flash` | 1M | 64K | Text Image Video | No |
***
### MiniMax
| Field | Value |
| - | - |
| **Provider ID** | `minimax` |
| **Base URL** | `https://api.minimax.io/v1` |
| **Website** | [minimax.io](https://www.minimax.io) |
| **API surfaces** | Chat Completions, Responses, Messages |
| **Provider key required** | No |
[How to use MiniMax →](/docs/ai-gateway/providers/minimax)
#### MiniMax models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `minimax-m3` | 1M | 512K | Text Image Video | No |
| `minimax-m2.7` | 200K | 200K | Text | No |
| `minimax-m2.7-highspeed` | 200K | 200K | Text | No |
| `minimax-m2.5` | 200K | 200K | Text | No |
| `minimax-m2.5-highspeed` | 200K | 200K | Text | No |
| `minimax-m2.1` | 200K | 200K | Text | No |
| `minimax-m2.1-highspeed` | 200K | 200K | Text | No |
| `minimax-m2` | 200K | 200K | Text | No |
***
### Tencent TokenHub
| Field | Value |
| - | - |
| **Provider ID** | `tokenhub` |
| **Base URL** | `https://tokenhub-intl.tencentcloudmaas.com/v1` |
| **Website** | [tencentcloud.com/document/product/1300](https://www.tencentcloud.com/document/product/1300) |
| **API surfaces** | Chat Completions, Responses, Messages |
| **Provider key required** | No |
[How to use Tencent TokenHub →](/docs/ai-gateway/providers/tokenhub)
#### Tencent TokenHub models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `xiaomi/mimo-v2.6-flash` | 1M | 64K | Text | No |
| `xiaomi/mimo-v2.6-pro` | 1M | 128K | Text | No |
| `stepfun/step-5-preview` | 1M | 64K | Text | No |
| `moonshotai/kimi-k2.8-preview` | 1M | — | Text Image Video | No |
| `deepseek/deepseek-flash` | 1M | 384K | Text | No |
| `tencent/hy4-preview` | 1M | 64K | Text | No |
| `z-ai/glm-5.3-flash` | 1M | 128K | Text Image Video File | No |
| `z-ai/glm-5.3` | 1M | 128K | Text | No |
| `deepseek/deepseek-v4-flash-0731` | 1M | 384K | Text | No |
| `deepseek/deepseek-v4-flash-202605` | 1M | 384K | Text | No |
| `moonshotai/kimi-k3` | 1M | 1M | Text Image Video | No |
| `tencent/hy3` | 256K | 128K | Text | No |
| `z-ai/glm-5.2` | 1M | 128K | Text | No |
| `moonshotai/kimi-k2.7-code` | 256K | 256K | Text Image Video | No |
| `moonshotai/kimi-k2.7-code-highspeed` | 256K | 256K | Text Image Video | No |
| `tencent/hy-mt2-lite` | 8K | 4K | Text | No |
| `tencent/hy-mt2-plus` | 8K | 4K | Text | No |
| `minimax/minimax-m3` | 1M | 512K | Text Image Video | No |
| `tencent/hy-mt2-pro` | 8K | 4K | Text | No |
| `xiaomi/mimo-v2.5-pro` | 1M | 128K | Text | No |
| `deepseek/deepseek-v4-flash` | 1M | 384K | Text | No |
| `deepseek/deepseek-v4-pro` | 1M | 384K | Text | No |
| `moonshotai/kimi-k2.6` | 256K | 256K | Text Image Video | No |
| `minimax/minimax-m2.7` | 200K | 200K | Text | No |
| `z-ai/glm-5.3-flashx` | 1M | 128K | Text Image Video File | No |
***
### Typesafe AI
| Field | Value |
| - | - |
| **Provider ID** | `typesafeai` |
| **Base URL** | `https://api.typesafe.ai/v1` |
| **Website** | [typesafe.ai](https://typesafe.ai) |
| **API surfaces** | System One |
| **Provider key required** | No |
[How to use Typesafe AI →](/docs/ai-gateway/providers/typesafeai)
#### Typesafe AI models
| Model ID | Context | Max Output | Modalities | Needs BYOK? |
| - | - | - | - | - |
| `jev-1.13.0` | 64K | — | Text | No |
| `jev-latest` | 64K | — | Text | No |
| `jev-preview` | 64K | — | Text | No |
***
### OpenRouter
| Field | Value |
| - | - |
| **Provider ID** | `openrouter` |
| **Base URL** | `https://openrouter.ai/api/v1` |
| **Website** | [openrouter.ai](https://openrouter.ai/) |
| **API surfaces** | Responses, Chat Completions, Messages |
| **Provider key required** | Yes |
[How to use OpenRouter →](/docs/ai-gateway/providers/openrouter)
OpenRouter is a unified API that provides access to multiple AI models from various providers through a single endpoint.
The catalog lists no models for OpenRouter. Send any model ID the provider serves with the `openrouter:` prefix, and the gateway passes it through.
***
### Hyperbolic
| Field | Value |
| - | - |
| **Provider ID** | `hyperbolic` |
| **Base URL** | `https://api.hyperbolic.xyz/v1` |
| **Website** | [hyperbolic.ai](https://www.hyperbolic.ai/) |
| **API surfaces** | Chat Completions |
| **Provider key required** | Yes |
[How to use Hyperbolic →](/docs/ai-gateway/providers/hyperbolic)
Hyperbolic provides high-performance inference for open-source models.
The catalog lists no models for Hyperbolic. Send any model ID the provider serves with the `hyperbolic:` prefix, and the gateway passes it through.
***
### InceptionLabs
| Field | Value |
| - | - |
| **Provider ID** | `inceptionlabs` |
| **Base URL** | `https://api.inceptionlabs.ai/v1` |
| **Website** | [inceptionlabs.ai](https://www.inceptionlabs.ai/) |
| **API surfaces** | Chat Completions |
| **Provider key required** | Yes |
[How to use InceptionLabs →](/docs/ai-gateway/providers/inceptionlabs)
InceptionLabs develops diffusion-based language models for fast, efficient text generation.
The catalog lists no models for InceptionLabs. Send any model ID the provider serves with the `inceptionlabs:` prefix, and the gateway passes it through.
***
### Inference.net
| Field | Value |
| - | - |
| **Provider ID** | `inference.net` |
| **Base URL** | `https://api.inference.net/v1` |
| **Website** | [inference.net](https://inference.net/) |
| **API surfaces** | Chat Completions |
| **Provider key required** | Yes |
[How to use Inference.net →](/docs/ai-gateway/providers/inference-net)
Inference.net provides a distributed inference network for running AI models at scale.
The catalog lists no models for Inference.net. Send any model ID the provider serves with the `inference.net:` prefix, and the gateway passes it through.
***
## Using models from the catalog
### Simple model reference
Reference models directly by their ID. A bare ID such as `gpt-4o` resolves to every provider that serves the model. The full catalog ID, such as `openai/gpt-4o`, works too:
```json theme={null}
{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}]
}
```
### Explicit provider
Use the `provider:model` format for explicit routing:
```json theme={null}
{
"model": "openai:gpt-4o",
"messages": [{"role": "user", "content": "Hello"}]
}
```
## Custom providers
Built-in providers cover major public APIs. For self-hosted models (Ollama, vLLM, LM Studio) or other endpoints, create a **custom provider** in the **Custom** tab in app.ngrok.ai. Custom providers always require a provider key when the upstream needs authentication.
See [Custom providers](/docs/ai-gateway/concepts/custom-providers) to add one.
## Catalog updates
The model catalog is updated periodically to include new models and providers. To use a model that isn't in the catalog yet, send it with its provider prefix, such as `groq:new-model-id`. The gateway passes it through to that provider. Uncataloged models need your own provider key, because ngrok.ai can't price them, so you can't pay for them with credits.
# Anthropic SDK
Source: https://ngrok.com/docs/ai-gateway/sdks/anthropic
Use the ngrok AI Gateway with Anthropic's official SDKs.
**Prerequisite**: Complete the [Quickstart](/docs/ai-gateway/quickstart) to get an [access key](/docs/ai-gateway/concepts/access-keys). All requests go to `https://gateway.ngrok.ai`.
The AI Gateway is compatible with Anthropic's official SDKs. Set the base URL to `https://gateway.ngrok.ai` and authenticate with your [access key](/docs/ai-gateway/concepts/access-keys).
Anthropic models also work through OpenAI-compatible SDKs (OpenAI SDK, Vercel AI SDK, LangChain, etc.)—just use the model name directly, for example `model: "claude-opus-4-6"`. You don't need the Anthropic SDK to access Anthropic models.
## Installation
```bash Python theme={null}
pip install anthropic
```
```bash TypeScript theme={null}
npm install @anthropic-ai/sdk
```
## Basic usage
Point the SDK at your AI Gateway endpoint:
```python Python highlight={4} theme={null}
import anthropic
client = anthropic.Anthropic(
base_url="https://gateway.ngrok.ai",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
)
print(message.content)
```
```typescript TypeScript highlight={4} theme={null}
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://gateway.ngrok.ai",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const message = await client.messages.create({
model: "claude-opus-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }],
});
console.log(message.content);
```
State your exact model name and provider.
The Anthropic SDK sends the API key via the `x-api-key` header. Access keys work with both `x-api-key` and `Authorization: Bearer` headers.
## Streaming
The AI Gateway supports streaming responses with the Anthropic SDK:
```python Python highlight={8} theme={null}
import anthropic
client = anthropic.Anthropic(
base_url="https://gateway.ngrok.ai",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
with client.messages.stream(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Write a haiku about APIs"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
```
```typescript TypeScript highlight={12} theme={null}
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://gateway.ngrok.ai",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const stream = await client.messages.create({
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello, Claude' }],
model: 'claude-opus-4-6',
stream: true,
});
for await (const messageStreamEvent of stream) {
console.log(messageStreamEvent.type);
}
```
Write a haiku about APIs
## Model failover
Specify fallback models in the request body. See [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models).
When using Anthropic SDKs with the gateway, model selection is limited to providers that support the Anthropic Claude API. Currently in the ngrok model catalog Anthropic is the only provider that supports this format.
## Tool use
Tool calling works as documented by Anthropic:
```python Python highlight={12-22} theme={null}
import anthropic
client = anthropic.Anthropic(
base_url="https://gateway.ngrok.ai",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "What's the weather in Paris?"}],
tools=[{
"name": "get_weather",
"description": "Get weather for a location",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string"}
},
"required": ["location"]
}
}]
)
print(message)
```
```typescript TypeScript highlight={12-22} theme={null}
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://gateway.ngrok.ai",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const message = await client.messages.create({
model: "claude-opus-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "What's the weather in Paris?" }],
tools: [
{
name: "get_weather",
description: "Get weather for a location",
input_schema: {
type: "object",
properties: {
location: { type: "string" },
},
required: ["location"],
},
},
],
});
console.log(message);
```
## Error handling
The gateway handles many errors automatically through failover. For errors that reach your app:
```python Python theme={null}
import anthropic
client = anthropic.Anthropic(
base_url="https://gateway.ngrok.ai",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
try:
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
)
except anthropic.RateLimitError as e:
print("Rate limited across all providers")
except anthropic.APIError as e:
print(f"API error: {e}")
```
```typescript TypeScript theme={null}
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://gateway.ngrok.ai",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
try {
const message = await client.messages.create({
model: "claude-opus-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }],
});
} catch (error) {
if (error instanceof Anthropic.RateLimitError) {
console.log("Rate limited across all providers");
} else if (error instanceof Anthropic.APIError) {
console.log(`API error: ${error.message}`);
}
}
```
## Supported endpoints
The AI Gateway supports these Anthropic Claude API endpoints:
| Endpoint | Description |
| - | - |
| `/v1/messages` | Messages |
| `/v1/files` | Files. See [Upload and use files](/docs/ai-gateway/guides/files) |
## Next steps
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Model IDs and provider prefixes
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model when the first one fails
* [Choose how to reach providers](/docs/ai-gateway/guides/configuring-providers): Credits, provider keys, and self-run models
# Google Gen AI SDK
Source: https://ngrok.com/docs/ai-gateway/sdks/google
Connect Google's Gen AI SDK to the ngrok AI Gateway with Python and TypeScript examples for GenerateContent, streaming, and stateless Interactions.
**Prerequisite**: Complete the [quickstart](/docs/ai-gateway/quickstart) to create an [access key](/docs/ai-gateway/concepts/access-keys).
See [Google provider setup](/docs/ai-gateway/providers/google#setup) to configure Google routing or bring your own Google key.
Use Google's Gen AI SDK for [Python](https://googleapis.github.io/python-genai/) or [TypeScript](https://googleapis.github.io/js-genai/) with the AI Gateway.
Set the base URL to `https://gateway.ngrok.ai`, use API version `v1beta`, and authenticate with your ngrok access key.
Google models also work through OpenAI-compatible Chat Completions.
See the [OpenAI SDK guide](/docs/ai-gateway/sdks/openai) to use your existing OpenAI client with a Google model name.
The OpenAI Responses API (`/v1/responses`) doesn't reach Google models.
## Installation
```bash Python theme={null}
pip install --upgrade google-genai
```
```bash TypeScript theme={null}
npm install @google/genai
```
## Basic usage
Set `NGROK_AI_GATEWAY_KEY` to your ngrok access key, then send a GenerateContent request:
```python Python highlight={7-11} theme={null}
import os
from google import genai
from google.genai import types
client = genai.Client(
api_key=os.environ["NGROK_AI_GATEWAY_KEY"],
http_options=types.HttpOptions(
base_url="https://gateway.ngrok.ai",
api_version="v1beta",
),
)
response = client.models.generate_content(
model="gemini-3.6-flash",
contents="Hello",
)
print(response.text)
```
```typescript TypeScript highlight={4-8} theme={null}
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({
apiKey: process.env.NGROK_AI_GATEWAY_KEY,
httpOptions: {
baseUrl: "https://gateway.ngrok.ai",
apiVersion: "v1beta",
},
});
const response = await client.models.generateContent({
model: "gemini-3.6-flash",
contents: "Hello",
});
console.log(response.text);
```
## Streaming
Use the SDK's streaming method to print text as it arrives:
```python Python highlight={14-19} theme={null}
import os
from google import genai
from google.genai import types
client = genai.Client(
api_key=os.environ["NGROK_AI_GATEWAY_KEY"],
http_options=types.HttpOptions(
base_url="https://gateway.ngrok.ai",
api_version="v1beta",
),
)
for chunk in client.models.generate_content_stream(
model="gemini-3.6-flash",
contents="Write a haiku about APIs",
):
if chunk.text:
print(chunk.text, end="", flush=True)
```
```typescript TypeScript highlight={11-18} theme={null}
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({
apiKey: process.env.NGROK_AI_GATEWAY_KEY,
httpOptions: {
baseUrl: "https://gateway.ngrok.ai",
apiVersion: "v1beta",
},
});
const stream = await client.models.generateContentStream({
model: "gemini-3.6-flash",
contents: "Write a haiku about APIs",
});
for await (const chunk of stream) {
process.stdout.write(chunk.text ?? "");
}
```
## Interactions
Send `model` and `input` to create a stateless interaction.
Set `store=false` explicitly:
```python Python highlight={14-18} theme={null}
import os
from google import genai
from google.genai import types
client = genai.Client(
api_key=os.environ["NGROK_AI_GATEWAY_KEY"],
http_options=types.HttpOptions(
base_url="https://gateway.ngrok.ai",
api_version="v1beta",
),
)
response = client.interactions.create(
model="gemini-3.6-flash",
input="Hello",
store=False,
)
print(response.output_text)
```
```typescript TypeScript highlight={11-15} theme={null}
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({
apiKey: process.env.NGROK_AI_GATEWAY_KEY,
httpOptions: {
baseUrl: "https://gateway.ngrok.ai",
apiVersion: "v1beta",
},
});
const response = await client.interactions.create({
model: "gemini-3.6-flash",
input: "Hello",
store: false,
});
console.log(response.output_text);
```
Interactions through the gateway are stateless.
The gateway rejects `store=true` and sends every valid request to Google with `store=false`, even if you omit `store` or set it to `null`.
Requests paid with credits and bring your own key (BYOK) requests both have these restrictions:
* Stored conversation chaining (`previous_interaction_id`) and background execution (`background=true`) are unsupported.
* Interaction retrieval, deletion, cancellation, and stream resumption are unsupported.
* Agents, environments, webhooks, and triggers are unsupported.
Interactions requests paid with credits support text input and text or structured JSON output only.
Use the Standard tier: omit `service_tier` or set it to `standard`.
The `gemini-3.1-pro-preview` and `gemini-3.1-pro-preview-customtools` models require BYOK for Interactions because they use context-band pricing.
With BYOK, supported input and output formats and service tiers depend on Google and the selected model.
## Authentication
Use your ngrok access key to authenticate requests to the gateway.
The gateway checks credentials in this order:
1. `Authorization: Bearer `
2. `X-Api-Key: `
3. `X-Goog-Api-Key: `, which the Google SDK sets from `api_key` in Python or `apiKey` in TypeScript.
The URL query parameter `key` fills an empty `X-Goog-Api-Key` header.
It doesn't override a header credential.
Prefer headers to keep credentials out of URLs.
Your access key identifies your gateway configuration.
A Google provider key is a separate credential stored in the gateway.
For BYOK, attach the stored Google key to your configuration; continue to send your ngrok access key from the client.
The gateway replaces client credentials with the selected Google provider credential before forwarding the request.
## Supported endpoints
The gateway supports these native Gemini endpoints:
| Endpoint | Description |
| - | - |
| `/v1beta/models/{model}:generateContent` | GenerateContent with a JSON response |
| `/v1beta/models/{model}:streamGenerateContent?alt=sse` | Streaming GenerateContent |
| `/v1beta/interactions` | Stateless Interactions with a JSON or streaming response |
### Generate content requests
Point a Gemini client at `https://gateway.ngrok.ai` and send your access key as described in [Authentication](#authentication).
Use `POST /v1beta/models/{model}:generateContent` for a JSON response.
For streaming, use `POST /v1beta/models/{model}:streamGenerateContent?alt=sse`.
The `alt=sse` query parameter is required.
```bash theme={null}
curl "https://gateway.ngrok.ai/v1beta/models/gemini-3.6-flash:generateContent" \
-H "X-Goog-Api-Key: ng-xxxxx-g1-xxxxx" \
-H "Content-Type: application/json" \
-d '{"contents":[{"parts":[{"text":"Hello"}]}]}'
```
Use Google's native GenerateContent payload format.
The gateway filters request parameters for the selected backend and applies output-token limits.
Responses include the gateway response headers: `Ngrok-AIG-Request-Id` on every response, `Ngrok-AIG-Attempts` once the upstream attempt loop runs, and `Ngrok-AIG-Model` on success.
See [Response headers](/docs/ai-gateway/how-it-works#response-headers).
### Interactions requests
Send `POST /v1beta/interactions` with `model` and `input` in the request body.
The REST base URL is `https://gateway.ngrok.ai/v1beta/`.
Omit `stream` or set it to `false` for a JSON response.
Set `stream=true` for server-sent events (SSE).
Responses use Google's native Interactions format and include the [gateway response headers](/docs/ai-gateway/how-it-works#response-headers).
```bash theme={null}
curl -X POST \
"https://gateway.ngrok.ai/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "X-Goog-Api-Key: ng-xxxxx-g1-xxxxx" \
-d '{
"model": "gemini-3.6-flash",
"input": "Hello!",
"store": false
}'
```
## Next steps
* [Configure Google as a provider](/docs/ai-gateway/providers/google)
* [Browse Google models](/docs/ai-gateway/reference/model-catalog#google)
* [Configure access keys](/docs/ai-gateway/guides/access-key-configurations)
# SDK Integration
Source: https://ngrok.com/docs/ai-gateway/sdks/index
Connect your SDK to the ngrok AI Gateway.
**Prerequisite**: Complete the [Quickstart](/docs/ai-gateway/quickstart) to create an access key on [app.ngrok.ai](https://app.ngrok.ai).
The AI Gateway works with official and third-party SDKs. Point the base URL at `https://gateway.ngrok.ai` and use your [access key](/docs/ai-gateway/concepts/access-keys).
## Supported SDKs
Official SDKs for Python, TypeScript, Go, Java, and .NET
Official SDKs for Python, TypeScript, Java, Go, Ruby, C#, and PHP
Official SDK examples for Python and TypeScript
Build AI apps with React, Next.js, and streaming
Type-safe AI library for React and Solid
Framework for chains, agents, and RAG
cURL, HTTP clients
## Quick start
The pattern is the same for any SDK—set the gateway URL and your [access key](/docs/ai-gateway/concepts/access-keys).
```python Python (OpenAI) theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
```
```python Python (Anthropic) theme={null}
import anthropic
client = anthropic.Anthropic(
base_url="https://gateway.ngrok.ai",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
```
```typescript TypeScript (OpenAI) theme={null}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
```
```typescript TypeScript (Anthropic) theme={null}
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://gateway.ngrok.ai",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
```
## What works through the gateway
| Feature | Supported |
| - | - |
| Chat Completions API | ✅ |
| Messages API | ✅ (Anthropic SDKs, on providers that support it) |
| Responses API | ✅ (providers that support it, see the [model catalog](/docs/ai-gateway/reference/model-catalog)) |
| GenerateContent API | ✅ (Google Gen AI SDK) |
| Interactions API | ✅ ([Stateless requests](/docs/ai-gateway/sdks/google#interactions)) |
| Streaming | ✅ |
| Function/tool calling | ✅ |
| Async clients | ✅ |
## Gateway benefits
Routing your SDK through the gateway gives you:
* Automatic failover that retries with the next key or model on failure.
* Provider switching by changing the model, with no integration code changes.
* One access key for multiple upstream providers.
## Using different providers
Use model prefixes or catalog names:
```python theme={null}
client.chat.completions.create(model="gpt-4o", ...) # OpenAI
client.chat.completions.create(model="claude-opus-4-6", ...) # Anthropic
client.chat.completions.create(model="openai:gpt-4o", ...) # Explicit provider
```
## Next steps
* [OpenAI SDK](/docs/ai-gateway/sdks/openai)
* [Anthropic SDK](/docs/ai-gateway/sdks/anthropic)
* [Google Gen AI SDK](/docs/ai-gateway/sdks/google)
* [Vercel AI SDK](/docs/ai-gateway/sdks/vercel-ai-sdk)
* [TanStack AI](/docs/ai-gateway/sdks/tanstack-ai)
* [LangChain](/docs/ai-gateway/sdks/langchain)
* [Other SDKs](/docs/ai-gateway/sdks/other)
# LangChain
Source: https://ngrok.com/docs/ai-gateway/sdks/langchain
Use the ngrok AI Gateway with LangChain.
**Prerequisite**: Complete the [Quickstart](/docs/ai-gateway/quickstart) to get an [access key](/docs/ai-gateway/concepts/access-keys). All requests go to `https://gateway.ngrok.ai`.
[LangChain](https://langchain.com/) is a framework for building applications with LLMs. The ngrok AI Gateway works with LangChain's OpenAI-compatible integrations, adding automatic failover and key rotation.
## Installation
```bash Python theme={null}
pip install langchain langchain-openai
```
```bash TypeScript theme={null}
npm install langchain @langchain/openai
```
## Basic usage
Configure LangChain to use your AI Gateway. Pass your [access key](/docs/ai-gateway/concepts/access-keys) (`ng-xxxxx-g1-xxxxx`) as the API key—the AI Gateway injects upstream provider credentials from your [access key configuration](/docs/ai-gateway/guides/access-key-configurations).
```python Python highlight={4} theme={null}
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx", # Your access key
model="gpt-4o"
)
response = llm.invoke("What is the capital of France?")
print(response.content)
```
```typescript TypeScript highlight={4} theme={null}
import { ChatOpenAI } from "@langchain/openai";
const llm = new ChatOpenAI({
configuration: {
baseURL: "https://gateway.ngrok.ai/v1",
},
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
model: "gpt-4o",
});
const response = await llm.invoke("What is the capital of France?");
console.log(response.content);
```
## Streaming
Stream responses for real-time output:
```python highlight={9} theme={null}
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx", # Your access key
model="gpt-4o"
)
for chunk in llm.stream("Write a poem about AI"):
print(chunk.content, end="", flush=True)
```
## Using different providers
Route to different providers with model prefixes:
```python highlight={7-8} theme={null}
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx", # Your access key
model="anthropic:claude-sonnet-4-6" # Use Anthropic through gateway
)
response = llm.invoke("Hello!")
```
## Chains
Build chains that route through the gateway:
```python highlight={4} theme={null}
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx", # Your access key
model="gpt-4o"
)
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant that translates {input_language} to {output_language}."),
("human", "{input}")
])
chain = prompt | llm
response = chain.invoke({
"input_language": "English",
"output_language": "French",
"input": "Hello, how are you?"
})
print(response.content)
```
## RAG applications
Build RAG applications with automatic failover. The AI Gateway doesn't serve embeddings, so create embeddings with your provider directly:
```python highlight={5} theme={null}
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx", # Your access key
model="gpt-4o"
)
# Embeddings go to OpenAI directly, not through the gateway
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
# Create vector store
texts = ["Document 1 content", "Document 2 content"]
vectorstore = FAISS.from_texts(texts, embeddings)
# Query with RAG
retriever = vectorstore.as_retriever()
docs = retriever.invoke("query")
prompt = ChatPromptTemplate.from_template(
"Answer based on context: {context}\n\nQuestion: {question}"
)
chain = prompt | llm
response = chain.invoke({"context": docs, "question": "Your question"})
```
## Agents
Build agents that use the gateway:
```python highlight={5} theme={null}
from langchain_openai import ChatOpenAI
from langchain.agents import create_react_agent, AgentExecutor
from langchain_core.tools import tool
llm = ChatOpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx", # Your access key
model="gpt-4o"
)
@tool
def search(query: str) -> str:
"""Search for information."""
return f"Results for: {query}"
# Create and run agent
# ...
```
## Next steps
* [LangChain Documentation](https://python.langchain.com/docs/) - Full LangChain reference
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Model IDs and provider prefixes
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model when the first one fails
* [Choose how to reach providers](/docs/ai-gateway/guides/configuring-providers): Credits, provider keys, and self-run models
# OpenAI SDK
Source: https://ngrok.com/docs/ai-gateway/sdks/openai
Use the ngrok AI Gateway with OpenAI's official SDKs.
**Prerequisite**: Complete the [Quickstart](/docs/ai-gateway/quickstart) to create an access key on app.ngrok.ai before continuing.
The AI Gateway is compatible with OpenAI's official SDKs. Set the base URL to `https://gateway.ngrok.ai/v1` and use your [access key](/docs/ai-gateway/concepts/access-keys).
## Installation
```bash Python theme={null}
pip install openai
```
```bash TypeScript theme={null}
npm install openai
```
## Basic usage
Point the SDK at your AI Gateway endpoint and pass your [access key](/docs/ai-gateway/concepts/access-keys) as `api_key`. See [Access keys vs provider keys](/docs/ai-gateway/concepts/access-keys#access-keys-vs-provider-keys) for how credentials flow through the gateway.
```python Python highlight={4} theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
```
```typescript TypeScript highlight={4} theme={null}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const response = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Hello!" }],
});
console.log(response.choices[0].message.content);
```
State your exact model name and provider.
## Streaming
The AI Gateway supports streaming responses:
```python Python highlight={8} theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
stream = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Write a haiku about APIs"}],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
```
```typescript TypeScript highlight={8} theme={null}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const stream = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Write a haiku about APIs" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
```
Write a haiku about APIs
## Using different providers
Route to different providers using model prefixes:
```python Python highlight={8-9} theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
# OpenAI
response = client.chat.completions.create(model="openai:gpt-4o", messages=[...])
# Anthropic (through the gateway)
response = client.chat.completions.create(model="anthropic:claude-sonnet-4-6", messages=[...])
# Your self-hosted Ollama
response = client.chat.completions.create(model="ollama:llama3.2", messages=[...])
```
```typescript TypeScript highlight={8-9} theme={null}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
// OpenAI
const openaiRes = await client.chat.completions.create({ model: "openai:gpt-4o", messages: [...] });
// Anthropic (through the gateway)
const anthropicRes = await client.chat.completions.create({ model: "anthropic:claude-sonnet-4-6", messages: [...] });
// Your self-hosted Ollama
const ollamaRes = await client.chat.completions.create({ model: "ollama:llama3.2", messages: [...] });
```
## Model failover
List fallback models in the request:
```python theme={null}
response = client.chat.completions.create(
model="gpt-4o",
extra_body={"models": ["gpt-4o-mini"]},
messages=[{"role": "user", "content": "Hello!"}],
)
```
To try another model when the first one fails, see [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models).
## Function calling
Tool/function calling works exactly as documented by OpenAI:
```python highlight={11-23} theme={null}
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "What's the weather in Paris?"}],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"}
}
}
}
}]
)
```
What is the current weather in Paris?
## Async usage
Use async clients for better performance:
```python Python theme={null}
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
async def main():
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
asyncio.run(main())
```
```typescript TypeScript theme={null}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
// TypeScript client is async by default
const response = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Hello!" }],
});
```
## Error handling
The gateway handles many errors automatically through failover. For errors that reach your app:
```python Python theme={null}
from openai import OpenAI, APIError, RateLimitError
client = OpenAI(
base_url="https://gateway.ngrok.ai/v1",
api_key="ng-xxxxx-g1-xxxxx" # Your access key
)
try:
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
except RateLimitError:
# All configured keys exhausted
print("Rate limited across all providers")
except APIError as e:
print(f"API error: {e}")
```
```typescript TypeScript theme={null}
import OpenAI, { APIError, RateLimitError } from "openai";
const client = new OpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
try {
const response = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Hello!" }],
});
} catch (e) {
if (e instanceof RateLimitError) {
// All configured keys exhausted
console.log("Rate limited across all providers");
} else if (e instanceof APIError) {
console.log(`API error: ${e.message}`);
}
}
```
## Supported endpoints
The AI Gateway supports these OpenAI API endpoints:
| Endpoint | Description |
| - | - |
| `/v1/chat/completions` | Chat completions |
| `/v1/responses` | Responses |
| `/v1/decisions` | Decisions. See [Typed-question APIs](/docs/ai-gateway/guides/decisions-and-system-one) |
| `/v1/files` | Files. See [Upload and use files](/docs/ai-gateway/guides/files) |
## Next steps
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies)
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models)
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations)
# Other SDKs
Source: https://ngrok.com/docs/ai-gateway/sdks/other
Use the ngrok AI Gateway with any SDK that supports OpenAI API or Anthropic Claude API format.
**Prerequisite**: Complete the [Quickstart](/docs/ai-gateway/quickstart) to get an [access key](/docs/ai-gateway/concepts/access-keys). All requests go to `https://gateway.ngrok.ai`.
The AI Gateway works with any SDK or HTTP client that supports OpenAI API or Anthropic Claude API format. If your language or framework isn't covered in the dedicated guides, you can still use the gateway.
## Requirements
For any SDK or client to work with the AI Gateway, it must:
1. Support the OpenAI API or Anthropic Claude API format
2. Allow customizing the base URL / endpoint
3. Send requests with proper authorization headers (for OpenAI API, `Authorization`; for Anthropic Claude API, `x-api-key`)
## Authentication
Pass your [access key](/docs/ai-gateway/concepts/access-keys) (`ng-xxxxx-g1-xxxxx`) as the API key. The AI Gateway injects upstream provider credentials from your [access key configuration](/docs/ai-gateway/guides/access-key-configurations).
## cURL
For testing or shell scripts:
```bash OpenAI API theme={null}
curl https://gateway.ngrok.ai/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ng-xxxxx-g1-xxxxx" \ # Your access key
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello!"}]
}'
```
```bash Anthropic Claude API theme={null}
curl https://gateway.ngrok.ai/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: ng-xxxxx-g1-xxxxx" \ # Your access key
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello!"}]
}'
```
## HTTP request format
Any HTTP client can call the AI Gateway:
```http OpenAI API theme={null}
POST /v1/chat/completions HTTP/1.1
Host: gateway.ngrok.ai
Content-Type: application/json
Authorization: Bearer ng-xxxxx-g1-xxxxx
{
"model": "gpt-4o",
"messages": [
{"role": "user", "content": "Hello!"}
]
}
```
```http Anthropic Claude API theme={null}
POST /v1/messages HTTP/1.1
Host: gateway.ngrok.ai
Content-Type: application/json
x-api-key: ng-xxxxx-g1-xxxxx
anthropic-version: 2023-06-01
{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Hello!"}
]
}
```
## Using provider prefixes
All clients support routing to specific providers using model prefixes:
```
# OpenAI
model: "openai:gpt-4o"
# Anthropic
model: "anthropic:claude-sonnet-4-6"
# Self-hosted
model: "ollama:llama3.2"
```
## Supported endpoints
The AI Gateway supports these endpoints:
| Endpoint | API Format | Description |
| - | - | - |
| `/v1/chat/completions` | OpenAI | Chat completions |
| `/v1/responses` | OpenAI | Responses |
| `/v1/models` | OpenAI | List available models |
| `/v1/messages` | Anthropic | Messages |
| `/v1/files` | OpenAI or Anthropic | Files. See [Upload and use files](/docs/ai-gateway/guides/files) |
| `/v1/decisions` | OpenAI | Decisions. See [Typed-question APIs](/docs/ai-gateway/guides/decisions-and-system-one) |
| `/v1/systemone` | Typesafe AI | System One. See [Typed-question APIs](/docs/ai-gateway/guides/decisions-and-system-one) |
## Next steps
* [OpenAI SDK](/docs/ai-gateway/sdks/openai) - Official Python, TypeScript, Go, Java, and .NET guide
* [Vercel AI SDK](/docs/ai-gateway/sdks/vercel-ai-sdk) - For Next.js and React applications
* [LangChain](/docs/ai-gateway/sdks/langchain) - For LangChain applications
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies)
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models)
# TanStack AI
Source: https://ngrok.com/docs/ai-gateway/sdks/tanstack-ai
Use the ngrok AI Gateway with TanStack AI.
**Prerequisite**: Complete the [Quickstart](/docs/ai-gateway/quickstart) to get an [access key](/docs/ai-gateway/concepts/access-keys). All requests go to `https://gateway.ngrok.ai`.
[TanStack AI](https://tanstack.com/ai) is a type-safe library for building AI applications with React, Solid, and other frameworks. It works with the ngrok AI Gateway through its OpenAI adapter.
## Installation
```bash theme={null}
npm install @tanstack/ai @tanstack/ai-openai
```
## Basic usage
Configure the OpenAI adapter to use your AI Gateway endpoint:
```typescript highlight={5} theme={null}
import { chat } from "@tanstack/ai";
import { openai } from "@tanstack/ai-openai";
const adapter = openai({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const stream = chat({
adapter,
messages: [{ role: "user", content: "Hello!" }],
model: "gpt-4o",
});
```
## Streaming responses
TanStack AI is built for streaming. Process chunks as they arrive:
```typescript highlight={10-12} theme={null}
import { chat } from "@tanstack/ai";
import { openai } from "@tanstack/ai-openai";
const adapter = openai({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const stream = chat({
adapter,
messages: [{ role: "user", content: "Write a poem about AI gateways." }],
model: "gpt-4o",
});
for await (const chunk of stream) {
// Process each chunk as it arrives
console.log(chunk);
}
```
## API route handler
Build API endpoints that stream responses:
```typescript title="app/api/chat/route.ts" highlight={5} theme={null}
import { chat, toStreamResponse } from "@tanstack/ai";
import { openai } from "@tanstack/ai-openai";
const adapter = openai({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
export async function POST(request: Request) {
const { messages } = await request.json();
const stream = chat({
adapter,
messages,
model: "gpt-4o",
});
return toStreamResponse(stream);
}
```
## Using different providers
The AI Gateway routes based on the model name. Use provider prefixes to target specific providers:
```typescript highlight={10-11} theme={null}
import { chat } from "@tanstack/ai";
import { openai } from "@tanstack/ai-openai";
const gateway = openai({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key // Gateway handles auth
});
// Use different providers through the same gateway
const openaiStream = chat({ adapter: gateway, model: "openai:gpt-4o", messages });
const anthropicStream = chat({ adapter: gateway, model: "anthropic:claude-sonnet-4-6", messages });
```
## Model failover
To try another model when the first one fails, see [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models).
## Tool calling
The AI Gateway supports function/tool calling:
```typescript highlight={10-20} theme={null}
import { chat, toolDefinition } from "@tanstack/ai";
import { openai } from "@tanstack/ai-openai";
import { z } from "zod";
const adapter = openai({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const getWeatherDef = toolDefinition({
name: "get_weather",
description: "Get the current weather",
inputSchema: z.object({
location: z.string().describe("The location to get weather for"),
}),
});
const getWeather = getWeatherDef.server(async ({ location }) => {
return { temperature: 72, conditions: "sunny" };
});
const stream = chat({
adapter,
messages: [{ role: "user", content: "What's the weather in San Francisco?" }],
model: "gpt-4o",
tools: [getWeather],
});
```
## Provider options
Pass provider-specific options for fine-grained control:
```typescript highlight={13-19} theme={null}
import { chat } from "@tanstack/ai";
import { openai } from "@tanstack/ai-openai";
const adapter = openai({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const stream = chat({
adapter,
messages,
model: "gpt-4o",
providerOptions: {
temperature: 0.7,
maxTokens: 1000,
topP: 0.9,
frequencyPenalty: 0.5,
presencePenalty: 0.5,
},
});
```
## React integration
Use TanStack AI with React for building chat interfaces:
```tsx title="app/page.tsx" theme={null}
"use client";
import { useChat } from "@tanstack/ai-react";
export default function Chat() {
const { messages, input, handleInputChange, handleSubmit } = useChat({
api: "/api/chat",
});
return (
{messages.map((m) => (
{m.role}: {m.content}
))}
);
}
```
## Environment variables
Set up your environment:
```bash title=".env.local" theme={null}
AI_GATEWAY_URL=https://gateway.ngrok.ai/v1
AI_GATEWAY_ACCESS_KEY=ng-xxxxx-g1-xxxxx
```
```typescript theme={null}
import { openai } from "@tanstack/ai-openai";
const adapter = openai({
baseURL: process.env.AI_GATEWAY_URL,
apiKey: process.env.AI_GATEWAY_ACCESS_KEY!,
});
```
## Next steps
* [TanStack AI Documentation](https://tanstack.com/ai/latest/docs)
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies)
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models)
* [Access key configurations](/docs/ai-gateway/guides/access-key-configurations)
# Vercel AI SDK
Source: https://ngrok.com/docs/ai-gateway/sdks/vercel-ai-sdk
Use the ngrok AI Gateway with Vercel's AI SDK.
**Prerequisite**: Complete the [Quickstart](/docs/ai-gateway/quickstart) to get an [access key](/docs/ai-gateway/concepts/access-keys). All requests go to `https://gateway.ngrok.ai`.
The [Vercel AI SDK](https://sdk.vercel.ai/) provides a unified interface for building AI applications. It works with the ngrok AI Gateway, adding provider failover, key rotation, and observability to Vercel's streaming and UI components.
## Installation
```bash theme={null}
npm install ai @ai-sdk/openai
```
## Basic usage
Point the OpenAI provider at your AI Gateway endpoint:
```typescript Next.js App Router highlight={5} theme={null}
import { generateText } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
const openai = createOpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const { text } = await generateText({
model: openai("gpt-4o"),
prompt: "What is the meaning of life?",
});
```
```typescript Edge Runtime highlight={5} theme={null}
import { generateText } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
const openai = createOpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
export const runtime = "edge";
export async function POST(req: Request) {
const { prompt } = await req.json();
const { text } = await generateText({
model: openai("gpt-4o"),
prompt,
});
return Response.json({ text });
}
```
## Streaming responses
The AI Gateway supports streaming. Use `streamText` for real-time responses:
```typescript highlight={9-12} theme={null}
import { streamText } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
const openai = createOpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const result = streamText({
model: openai("gpt-4o"),
prompt: "Write a poem about AI gateways.",
});
for await (const textPart of result.textStream) {
process.stdout.write(textPart);
}
```
## Chat interface
Build chat applications with the `useChat` hook:
```tsx title="app/page.tsx" highlight={7} theme={null}
"use client";
import { useChat } from "ai/react";
export default function Chat() {
const { messages, input, handleInputChange, handleSubmit } = useChat({
api: "/api/chat",
});
return (
{messages.map((m) => (
{m.role}: {m.content}
))}
);
}
```
```typescript title="app/api/chat/route.ts" highlight={5} theme={null}
import { streamText } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
const openai = createOpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai("gpt-4o"),
messages,
});
return result.toDataStreamResponse();
}
```
## Using different providers
The AI Gateway routes based on the model name. Use provider prefixes to be explicit:
```typescript highlight={10-11} theme={null}
import { generateText } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
const gateway = createOpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
// Use different providers through the same gateway
const openaiResult = await generateText({ model: gateway("openai:gpt-4o"), prompt: "Hello" });
const anthropicResult = await generateText({ model: gateway("anthropic:claude-sonnet-4-6"), prompt: "Hello" });
```
## Model failover
List fallback models in the request. See [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models).
## Environment variables
Set up your environment:
```bash title=".env.local" theme={null}
AI_GATEWAY_URL=https://gateway.ngrok.ai/v1
AI_GATEWAY_ACCESS_KEY=ng-xxxxx-g1-xxxxx
```
```typescript theme={null}
const openai = createOpenAI({
baseURL: process.env.AI_GATEWAY_URL,
apiKey: process.env.AI_GATEWAY_ACCESS_KEY!,
});
```
## Tool calling
The AI Gateway supports function/tool calling:
```typescript highlight={12-22} theme={null}
import { generateText, tool } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
import { z } from "zod";
const openai = createOpenAI({
baseURL: "https://gateway.ngrok.ai/v1",
apiKey: "ng-xxxxx-g1-xxxxx", // Your access key
});
const { text, toolCalls } = await generateText({
model: openai("gpt-4o"),
tools: {
weather: tool({
description: "Get the weather in a location",
parameters: z.object({
location: z.string().describe("The location to get weather for"),
}),
execute: async ({ location }) => {
return { temperature: 72, condition: "sunny" };
},
}),
},
prompt: "What's the weather in San Francisco?",
});
```
## Error handling
Handle errors gracefully:
```typescript theme={null}
import { generateText, APICallError } from "ai";
try {
const { text } = await generateText({
model: openai("gpt-4o"),
prompt: "Hello",
});
} catch (error) {
if (error instanceof APICallError) {
console.error("API Error:", error.message);
console.error("Status:", error.statusCode);
}
}
```
With the AI Gateway's failover, many errors are handled automatically by retrying with different providers or keys.
## Next steps
* [Vercel AI SDK Documentation](https://sdk.vercel.ai/docs) - Full SDK reference
* [Choose a model](/docs/ai-gateway/guides/model-selection-strategies): Model IDs and provider prefixes
* [Configure fallback models](/docs/ai-gateway/guides/configure-fallback-models): Try another model when the first one fails
* [Choose how to reach providers](/docs/ai-gateway/guides/configuring-providers): Credits, provider keys, and self-run models
# Create
Source: https://ngrok.com/docs/api-reference/abusereports/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /abuse_reports
Creates a new abuse report which will be reviewed by our system and abuse response team. This API is only available to authorized accounts. Contact abuse@ngrok.com to request access
# Get
Source: https://ngrok.com/docs/api-reference/abusereports/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /abuse_reports/{id}
Get the detailed status of abuse report by ID.
# Create
Source: https://ngrok.com/docs/api-reference/agentingresses/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /agent_ingresses
Create a new Agent Ingress. The ngrok agent can be configured to connect to ngrok via the new set of addresses on the returned Agent Ingress.
# Delete
Source: https://ngrok.com/docs/api-reference/agentingresses/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /agent_ingresses/{id}
Delete an Agent Ingress by ID
# Get
Source: https://ngrok.com/docs/api-reference/agentingresses/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /agent_ingresses/{id}
Get the details of an Agent Ingress by ID.
# List
Source: https://ngrok.com/docs/api-reference/agentingresses/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /agent_ingresses
List all Agent Ingresses owned by this account
# Update
Source: https://ngrok.com/docs/api-reference/agentingresses/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /agent_ingresses/{id}
Update attributes of an Agent Ingress by ID.
# Create
Source: https://ngrok.com/docs/api-reference/apikeys/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /api_keys
Create a new API key. The generated API key can be used to authenticate to the ngrok API.
# Delete
Source: https://ngrok.com/docs/api-reference/apikeys/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /api_keys/{id}
Delete an API key by ID
# Get
Source: https://ngrok.com/docs/api-reference/apikeys/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /api_keys/{id}
Get the details of an API key by ID.
# List
Source: https://ngrok.com/docs/api-reference/apikeys/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /api_keys
List all API keys owned by this account
# Update
Source: https://ngrok.com/docs/api-reference/apikeys/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /api_keys/{id}
Update attributes of an API key by ID.
# Delete
Source: https://ngrok.com/docs/api-reference/applicationsessions/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /app/sessions/{id}
Delete an application session by ID.
# Get
Source: https://ngrok.com/docs/api-reference/applicationsessions/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /app/sessions/{id}
Get an application session by ID.
# List
Source: https://ngrok.com/docs/api-reference/applicationsessions/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /app/sessions
List all application sessions for this account.
# Delete
Source: https://ngrok.com/docs/api-reference/applicationusers/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /app/users/{id}
Delete an application user by ID.
# Get
Source: https://ngrok.com/docs/api-reference/applicationusers/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /app/users/{id}
Get an application user by ID.
# List
Source: https://ngrok.com/docs/api-reference/applicationusers/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /app/users
List all application users for this account.
# Create
Source: https://ngrok.com/docs/api-reference/botusers/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /bot_users
Create a new bot user
# Delete
Source: https://ngrok.com/docs/api-reference/botusers/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /bot_users/{id}
Delete a bot user by ID
# Get
Source: https://ngrok.com/docs/api-reference/botusers/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /bot_users/{id}
Get the details of a Bot User by ID.
# List
Source: https://ngrok.com/docs/api-reference/botusers/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /bot_users
List all bot users in this account.
# Update
Source: https://ngrok.com/docs/api-reference/botusers/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /bot_users/{id}
Update attributes of a bot user by ID.
# Create
Source: https://ngrok.com/docs/api-reference/certificateauthorities/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /certificate_authorities
Upload a new Certificate Authority
# Delete
Source: https://ngrok.com/docs/api-reference/certificateauthorities/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /certificate_authorities/{id}
Delete a Certificate Authority
# Get
Source: https://ngrok.com/docs/api-reference/certificateauthorities/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /certificate_authorities/{id}
Get detailed information about a certificate authority
# List
Source: https://ngrok.com/docs/api-reference/certificateauthorities/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /certificate_authorities
List all Certificate Authority on this account
# Update
Source: https://ngrok.com/docs/api-reference/certificateauthorities/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /certificate_authorities/{id}
Update attributes of a Certificate Authority by ID
# Create
Source: https://ngrok.com/docs/api-reference/credentials/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /credentials
Create a new tunnel authtoken credential. This authtoken credential can be used to start a new tunnel session. The response to this API call is the only time the generated token is available. If you need it for future use, you must save it securely yourself.
# Delete
Source: https://ngrok.com/docs/api-reference/credentials/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /credentials/{id}
Delete a tunnel authtoken credential by ID
# Get
Source: https://ngrok.com/docs/api-reference/credentials/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /credentials/{id}
Get detailed information about a tunnel authtoken credential
# List
Source: https://ngrok.com/docs/api-reference/credentials/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /credentials
List all tunnel authtoken credentials on this account
# Update
Source: https://ngrok.com/docs/api-reference/credentials/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /credentials/{id}
Update attributes of an tunnel authtoken credential by ID
# Delete
Source: https://ngrok.com/docs/api-reference/edgeroutebackendmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/backend
# Get
Source: https://ngrok.com/docs/api-reference/edgeroutebackendmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/backend
# Replace
Source: https://ngrok.com/docs/api-reference/edgeroutebackendmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/backend
# Delete
Source: https://ngrok.com/docs/api-reference/edgeroutecircuitbreakermodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/circuit_breaker
# Get
Source: https://ngrok.com/docs/api-reference/edgeroutecircuitbreakermodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/circuit_breaker
# Replace
Source: https://ngrok.com/docs/api-reference/edgeroutecircuitbreakermodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/circuit_breaker
# Delete
Source: https://ngrok.com/docs/api-reference/edgeroutecompressionmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/compression
# Get
Source: https://ngrok.com/docs/api-reference/edgeroutecompressionmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/compression
# Replace
Source: https://ngrok.com/docs/api-reference/edgeroutecompressionmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/compression
# Delete
Source: https://ngrok.com/docs/api-reference/edgerouteiprestrictionmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/ip_restriction
# Get
Source: https://ngrok.com/docs/api-reference/edgerouteiprestrictionmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/ip_restriction
# Replace
Source: https://ngrok.com/docs/api-reference/edgerouteiprestrictionmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/ip_restriction
# Delete
Source: https://ngrok.com/docs/api-reference/edgerouteoauthmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/oauth
# Get
Source: https://ngrok.com/docs/api-reference/edgerouteoauthmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/oauth
# Replace
Source: https://ngrok.com/docs/api-reference/edgerouteoauthmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/oauth
# Delete
Source: https://ngrok.com/docs/api-reference/edgerouteoidcmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/oidc
# Get
Source: https://ngrok.com/docs/api-reference/edgerouteoidcmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/oidc
# Replace
Source: https://ngrok.com/docs/api-reference/edgerouteoidcmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/oidc
# Delete
Source: https://ngrok.com/docs/api-reference/edgerouterequestheadersmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/request_headers
# Get
Source: https://ngrok.com/docs/api-reference/edgerouterequestheadersmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/request_headers
# Replace
Source: https://ngrok.com/docs/api-reference/edgerouterequestheadersmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/request_headers
# Delete
Source: https://ngrok.com/docs/api-reference/edgerouteresponseheadersmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/response_headers
# Get
Source: https://ngrok.com/docs/api-reference/edgerouteresponseheadersmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/response_headers
# Replace
Source: https://ngrok.com/docs/api-reference/edgerouteresponseheadersmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/response_headers
# Delete
Source: https://ngrok.com/docs/api-reference/edgeroutesamlmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/saml
# Get
Source: https://ngrok.com/docs/api-reference/edgeroutesamlmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/saml
# Replace
Source: https://ngrok.com/docs/api-reference/edgeroutesamlmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/saml
# Delete
Source: https://ngrok.com/docs/api-reference/edgeroutetrafficpolicymodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/traffic_policy
# Get
Source: https://ngrok.com/docs/api-reference/edgeroutetrafficpolicymodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/traffic_policy
# Replace
Source: https://ngrok.com/docs/api-reference/edgeroutetrafficpolicymodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/traffic_policy
# Delete
Source: https://ngrok.com/docs/api-reference/edgerouteuseragentfiltermodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/user_agent_filter
# Get
Source: https://ngrok.com/docs/api-reference/edgerouteuseragentfiltermodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/user_agent_filter
# Replace
Source: https://ngrok.com/docs/api-reference/edgerouteuseragentfiltermodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/user_agent_filter
# Delete
Source: https://ngrok.com/docs/api-reference/edgeroutewebhookverificationmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/webhook_verification
# Get
Source: https://ngrok.com/docs/api-reference/edgeroutewebhookverificationmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/webhook_verification
# Replace
Source: https://ngrok.com/docs/api-reference/edgeroutewebhookverificationmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/webhook_verification
# Delete
Source: https://ngrok.com/docs/api-reference/edgeroutewebsockettcpconvertermodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}/websocket_tcp_converter
# Get
Source: https://ngrok.com/docs/api-reference/edgeroutewebsockettcpconvertermodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}/websocket_tcp_converter
# Replace
Source: https://ngrok.com/docs/api-reference/edgeroutewebsockettcpconvertermodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{edge_id}/routes/{id}/websocket_tcp_converter
# Create
Source: https://ngrok.com/docs/api-reference/edgeshttps/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /edges/https
Create an HTTPS Edge
# Delete
Source: https://ngrok.com/docs/api-reference/edgeshttps/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{id}
Delete an HTTPS Edge by ID
# Get
Source: https://ngrok.com/docs/api-reference/edgeshttps/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{id}
Get an HTTPS Edge by ID
# List
Source: https://ngrok.com/docs/api-reference/edgeshttps/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https
Returns a list of all HTTPS Edges on this account
# Update
Source: https://ngrok.com/docs/api-reference/edgeshttps/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /edges/https/{id}
Updates an HTTPS Edge by ID. If a module is not specified in the update, it will not be modified. However, each module configuration that is specified will completely replace the existing value. There is no way to delete an existing module via this API, instead use the delete module API.
# Create
Source: https://ngrok.com/docs/api-reference/edgeshttpsroutes/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /edges/https/{edge_id}/routes
Create an HTTPS Edge Route
# Delete
Source: https://ngrok.com/docs/api-reference/edgeshttpsroutes/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{edge_id}/routes/{id}
Delete an HTTPS Edge Route by ID
# Get
Source: https://ngrok.com/docs/api-reference/edgeshttpsroutes/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{edge_id}/routes/{id}
Get an HTTPS Edge Route by ID
# Update
Source: https://ngrok.com/docs/api-reference/edgeshttpsroutes/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /edges/https/{edge_id}/routes/{id}
Updates an HTTPS Edge Route by ID. If a module is not specified in the update, it will not be modified. However, each module configuration that is specified will completely replace the existing value. There is no way to delete an existing module via this API, instead use the delete module API.
# Create
Source: https://ngrok.com/docs/api-reference/edgestcp/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /edges/tcp
Create a TCP Edge
# Delete
Source: https://ngrok.com/docs/api-reference/edgestcp/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/tcp/{id}
Delete a TCP Edge by ID
# Get
Source: https://ngrok.com/docs/api-reference/edgestcp/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tcp/{id}
Get a TCP Edge by ID
# List
Source: https://ngrok.com/docs/api-reference/edgestcp/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tcp
Returns a list of all TCP Edges on this account
# Update
Source: https://ngrok.com/docs/api-reference/edgestcp/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /edges/tcp/{id}
Updates a TCP Edge by ID. If a module is not specified in the update, it will not be modified. However, each module configuration that is specified will completely replace the existing value. There is no way to delete an existing module via this API, instead use the delete module API.
# Create
Source: https://ngrok.com/docs/api-reference/edgestls/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /edges/tls
Create a TLS Edge
# Delete
Source: https://ngrok.com/docs/api-reference/edgestls/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/tls/{id}
Delete a TLS Edge by ID
# Get
Source: https://ngrok.com/docs/api-reference/edgestls/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tls/{id}
Get a TLS Edge by ID
# List
Source: https://ngrok.com/docs/api-reference/edgestls/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tls
Returns a list of all TLS Edges on this account
# Update
Source: https://ngrok.com/docs/api-reference/edgestls/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /edges/tls/{id}
Updates a TLS Edge by ID. If a module is not specified in the update, it will not be modified. However, each module configuration that is specified will completely replace the existing value. There is no way to delete an existing module via this API, instead use the delete module API.
# Create
Source: https://ngrok.com/docs/api-reference/endpoints/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /endpoints
Create an endpoint, currently available only for cloud endpoints
# Delete
Source: https://ngrok.com/docs/api-reference/endpoints/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /endpoints/{id}
Delete an Endpoint by ID, currently available only for cloud endpoints
# Get
Source: https://ngrok.com/docs/api-reference/endpoints/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /endpoints/{id}
Get the status of an endpoint by ID
# List
Source: https://ngrok.com/docs/api-reference/endpoints/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /endpoints
List all active endpoints on the account
# Update
Source: https://ngrok.com/docs/api-reference/endpoints/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /endpoints/{id}
Update an Endpoint by ID, currently available only for cloud endpoints
# Create
Source: https://ngrok.com/docs/api-reference/eventdestinations/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /event_destinations
Create a new Event Destination. It will not apply to anything until it is associated with an Event Subscription.
# Delete
Source: https://ngrok.com/docs/api-reference/eventdestinations/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /event_destinations/{id}
Delete an Event Destination. If the Event Destination is still referenced by an Event Subscription.
# Get
Source: https://ngrok.com/docs/api-reference/eventdestinations/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /event_destinations/{id}
Get detailed information about an Event Destination by ID.
# List
Source: https://ngrok.com/docs/api-reference/eventdestinations/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /event_destinations
List all Event Destinations on this account.
# Update
Source: https://ngrok.com/docs/api-reference/eventdestinations/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /event_destinations/{id}
Update attributes of an Event Destination.
# Create
Source: https://ngrok.com/docs/api-reference/eventsources/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /event_subscriptions/{subscription_id}/sources
Add an additional type for which this event subscription will trigger
# Delete
Source: https://ngrok.com/docs/api-reference/eventsources/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /event_subscriptions/{subscription_id}/sources/{type}
Remove a type for which this event subscription will trigger
# Get
Source: https://ngrok.com/docs/api-reference/eventsources/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /event_subscriptions/{subscription_id}/sources/{type}
Get the details for a given type that triggers for the given event subscription
# List
Source: https://ngrok.com/docs/api-reference/eventsources/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /event_subscriptions/{subscription_id}/sources
List the types for which this event subscription will trigger
# Update
Source: https://ngrok.com/docs/api-reference/eventsources/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /event_subscriptions/{subscription_id}/sources/{type}
Update the type for which this event subscription will trigger
# Create
Source: https://ngrok.com/docs/api-reference/eventsubscriptions/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /event_subscriptions
Create an Event Subscription.
# Delete
Source: https://ngrok.com/docs/api-reference/eventsubscriptions/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /event_subscriptions/{id}
Delete an Event Subscription.
# Get
Source: https://ngrok.com/docs/api-reference/eventsubscriptions/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /event_subscriptions/{id}
Get an Event Subscription by ID.
# List
Source: https://ngrok.com/docs/api-reference/eventsubscriptions/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /event_subscriptions
List this Account's Event Subscriptions.
# Update
Source: https://ngrok.com/docs/api-reference/eventsubscriptions/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /event_subscriptions/{id}
Update an Event Subscription.
# Create
Source: https://ngrok.com/docs/api-reference/failoverbackends/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /backends/failover
Create a new Failover backend
# Delete
Source: https://ngrok.com/docs/api-reference/failoverbackends/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /backends/failover/{id}
Delete a Failover backend by ID.
# Get
Source: https://ngrok.com/docs/api-reference/failoverbackends/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /backends/failover/{id}
Get detailed information about a Failover backend by ID
# List
Source: https://ngrok.com/docs/api-reference/failoverbackends/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /backends/failover
List all Failover backends on this account
# Update
Source: https://ngrok.com/docs/api-reference/failoverbackends/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /backends/failover/{id}
Update Failover backend by ID
# Create
Source: https://ngrok.com/docs/api-reference/httpresponsebackends/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /backends/http_response
# Delete
Source: https://ngrok.com/docs/api-reference/httpresponsebackends/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /backends/http_response/{id}
# Get
Source: https://ngrok.com/docs/api-reference/httpresponsebackends/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /backends/http_response/{id}
# List
Source: https://ngrok.com/docs/api-reference/httpresponsebackends/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /backends/http_response
# Update
Source: https://ngrok.com/docs/api-reference/httpresponsebackends/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /backends/http_response/{id}
# Delete
Source: https://ngrok.com/docs/api-reference/httpsedgemutualtlsmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{id}/mutual_tls
# Get
Source: https://ngrok.com/docs/api-reference/httpsedgemutualtlsmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{id}/mutual_tls
# Replace
Source: https://ngrok.com/docs/api-reference/httpsedgemutualtlsmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{id}/mutual_tls
# Delete
Source: https://ngrok.com/docs/api-reference/httpsedgetlsterminationmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/https/{id}/tls_termination
# Get
Source: https://ngrok.com/docs/api-reference/httpsedgetlsterminationmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/https/{id}/tls_termination
# Replace
Source: https://ngrok.com/docs/api-reference/httpsedgetlsterminationmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/https/{id}/tls_termination
# Create
Source: https://ngrok.com/docs/api-reference/ippolicies/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /ip_policies
Create a new IP policy. It will not apply to any traffic until you associate to a traffic source via an endpoint configuration or IP restriction.
# Delete
Source: https://ngrok.com/docs/api-reference/ippolicies/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /ip_policies/{id}
Delete an IP policy. If the IP policy is referenced by another object for the purposes of traffic restriction it will be treated as if the IP policy remains but has zero rules.
# Get
Source: https://ngrok.com/docs/api-reference/ippolicies/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ip_policies/{id}
Get detailed information about an IP policy by ID.
# List
Source: https://ngrok.com/docs/api-reference/ippolicies/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ip_policies
List all IP policies on this account
# Update
Source: https://ngrok.com/docs/api-reference/ippolicies/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /ip_policies/{id}
Update attributes of an IP policy by ID
# Create
Source: https://ngrok.com/docs/api-reference/ippolicyrules/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /ip_policy_rules
Create a new IP policy rule attached to an IP Policy.
# Delete
Source: https://ngrok.com/docs/api-reference/ippolicyrules/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /ip_policy_rules/{id}
Delete an IP policy rule.
# Get
Source: https://ngrok.com/docs/api-reference/ippolicyrules/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ip_policy_rules/{id}
Get detailed information about an IP policy rule by ID.
# List
Source: https://ngrok.com/docs/api-reference/ippolicyrules/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ip_policy_rules
List all IP policy rules on this account
# Update
Source: https://ngrok.com/docs/api-reference/ippolicyrules/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /ip_policy_rules/{id}
Update attributes of an IP policy rule by ID
# Create
Source: https://ngrok.com/docs/api-reference/iprestrictions/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /ip_restrictions
Create a new IP restriction
# Delete
Source: https://ngrok.com/docs/api-reference/iprestrictions/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /ip_restrictions/{id}
Delete an IP restriction
# Get
Source: https://ngrok.com/docs/api-reference/iprestrictions/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ip_restrictions/{id}
Get detailed information about an IP restriction
# List
Source: https://ngrok.com/docs/api-reference/iprestrictions/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ip_restrictions
List all IP restrictions on this account
# Update
Source: https://ngrok.com/docs/api-reference/iprestrictions/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /ip_restrictions/{id}
Update attributes of an IP restriction by ID
# Kubernetes Operators
Source: https://ngrok.com/docs/api-reference/kubernetes-operators
API reference documentation for Kubernetes Operator endpoints used by the ngrok Kubernetes Operator to manage operator state.
These endpoints are not intended to be accessed directly by users. They exist to be accessed by the [Kubernetes Operator](/docs/k8s). They are documented here for completeness.
## Create Kubernetes Operator
Create a new Kubernetes Operator
### Request
POST /kubernetes\_operators
#### Example Request
```bash theme={null}
curl \
-X POST \
-H "Authorization: Bearer {API_KEY}" \
-H "Content-Type: application/json" \
-H "Ngrok-Version: 2" \
-d '{"deployment":{"name":"ngrok-operator","namespace":"ngrok-operator"},"description":"Example Kubernetes Operator","enabled_features":["Ingress"],"metadata":"{\"environment\": \"staging\"}","region":"global"}' \
https://api.ngrok.com/kubernetes_operators
```
#### Parameters
| Name | Type | Description |
| - | - | - |
| `description` | string | human-readable description of this Kubernetes Operator. optional, max 255 bytes. |
| `metadata` | string | arbitrary user-defined machine-readable data of this Kubernetes Operator. optional, max 4096 bytes. |
| `enabled_features` | List\ | features enabled for this Kubernetes Operator. a subset of "bindings", "ingress", and "gateway" |
| `region` | string | the ngrok region in which the ingress for this Operator is served. defaults to "global" |
| `deployment` | [KubernetesOperatorDeployment](#kubernetesoperatordeployment-parameters) | information about the deployment of this Kubernetes Operator |
| `binding` | [KubernetesOperatorBindingCreate](#kubernetesoperatorbindingcreate-parameters) | configuration for the Bindings feature of this Kubernetes Operator. set only if enabling the "bindings" feature |
#### KubernetesOperatorDeployment parameters
| Name | Type | Description |
| - | - | - |
| `name` | string | the deployment name |
| `namespace` | string | the namespace this Kubernetes Operator is deployed to |
| `version` | string | the version of this Kubernetes Operator |
| `cluster_name` | string | user-given name for the cluster the Kubernetes Operator is deployed to |
#### KubernetesOperatorBindingCreate parameters
| Name | Type | Description |
| - | - | - |
| `endpoint_selectors` | List\ | the list of cel expressions that filter the k8s bound endpoints for this Operator |
| `csr` | string | CSR is supplied during initial creation to enable creating a mutual TLS secured connection between ngrok and the Operator. This is an internal implementation detail and subject to change. |
| `ingress_endpoint` | string | the public ingress endpoint for this Kubernetes Operator |
### Response
Returns a 201 response on success
#### Example Response
```json theme={null}
{
"binding": {
"cert": {
"cert": "",
"not_after": "0001-01-01T00:00:00Z",
"not_before": "0001-01-01T00:00:00Z"
},
"endpoint_selectors": null
},
"created_at": "2025-09-04T10:11:43Z",
"deployment": {
"cluster_name": "",
"name": "ngrok-operator",
"namespace": "ngrok-operator",
"version": ""
},
"description": "Example Kubernetes Operator",
"enabled_features": [
"ingress"
],
"id": "k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT",
"metadata": "{\"environment\": \"staging\"}",
"principal": {
"id": "usr_32ELAUA7XkJHRP2DgH2JjDRLp81",
"uri": ""
},
"region": "global",
"updated_at": "2025-09-04T10:11:43Z",
"uri": "https://api.ngrok.com/kubernetes_operators/k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT"
}
```
#### Fields
| Name | Type | Description |
| - | - | - |
| `id` | string | unique identifier for this Kubernetes Operator |
| `uri` | string | URI of this Kubernetes Operator API resource |
| `created_at` | string | timestamp when the Kubernetes Operator was created. RFC 3339 format |
| `updated_at` | string | timestamp when the Kubernetes Operator was last updated. RFC 3339 format |
| `description` | string | human-readable description of this Kubernetes Operator. optional, max 255 bytes. |
| `metadata` | string | arbitrary user-defined machine-readable data of this Kubernetes Operator. optional, max 4096 bytes. |
| `principal` | [Ref](#ref-fields) | the principal who created this Kubernetes Operator |
| `enabled_features` | List\ | features enabled for this Kubernetes Operator. a subset of "bindings", "ingress", and "gateway" |
| `region` | string | the ngrok region in which the ingress for this Operator is served. defaults to "global" |
| `deployment` | [KubernetesOperatorDeployment](#kubernetesoperatordeployment-fields) | information about the deployment of this Kubernetes Operator |
| `binding` | [KubernetesOperatorBinding](#kubernetesoperatorbinding-fields) | information about the Bindings feature of this Kubernetes Operator, if enabled |
#### Ref fields
| Name | Type | Description |
| - | - | - |
| `id` | string | a resource identifier |
| `uri` | string | a uri for locating a resource |
#### KubernetesOperatorDeployment fields
| Name | Type | Description |
| - | - | - |
| `name` | string | the deployment name |
| `namespace` | string | the namespace this Kubernetes Operator is deployed to |
| `version` | string | the version of this Kubernetes Operator |
| `cluster_name` | string | user-given name for the cluster the Kubernetes Operator is deployed to |
#### KubernetesOperatorBinding fields
| Name | Type | Description |
| - | - | - |
| `endpoint_selectors` | List\ | the list of cel expressions that filter the k8s bound endpoints for this Operator |
| `cert` | [KubernetesOperatorCert](#kubernetesoperatorcert-fields) | the binding certificate information |
| `ingress_endpoint` | string | the public ingress endpoint for this Kubernetes Operator |
#### KubernetesOperatorCert fields
| Name | Type | Description |
| - | - | - |
| `cert` | string | the public client certificate generated for this Kubernetes Operator from the CSR supplied when enabling the Bindings feature |
| `not_before` | string | timestamp when the certificate becomes valid. RFC 3339 format |
| `not_after` | string | timestamp when the certificate becomes invalid. RFC 3339 format |
## Update Kubernetes Operator
Update an existing Kubernetes Operator by ID.
### Request
PATCH /kubernetes\_operators/\{id}
#### Example Request
```bash theme={null}
curl \
-X PATCH \
-H "Authorization: Bearer {API_KEY}" \
-H "Content-Type: application/json" \
-H "Ngrok-Version: 2" \
-d '{"metadata":"{\"environment\": \"production\"}"}' \
https://api.ngrok.com/kubernetes_operators/k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT
```
#### Parameters
| Name | Type | Description |
| - | - | - |
| `id` | string | unique identifier for this Kubernetes Operator |
| `description` | string | human-readable description of this Kubernetes Operator. optional, max 255 bytes. |
| `metadata` | string | arbitrary user-defined machine-readable data of this Kubernetes Operator. optional, max 4096 bytes. |
| `enabled_features` | List\ | features enabled for this Kubernetes Operator. a subset of "bindings", "ingress", and "gateway" |
| `region` | string | the ngrok region in which the ingress for this Operator is served. defaults to "global" |
| `binding` | [KubernetesOperatorBindingUpdate](#kubernetesoperatorbindingupdate-parameters) | configuration for the Bindings feature of this Kubernetes Operator. set only if enabling the "bindings" feature |
| `deployment` | [KubernetesOperatorDeploymentUpdate](#kubernetesoperatordeploymentupdate-parameters) | configuration for the Deployment info |
#### KubernetesOperatorBindingUpdate parameters
| Name | Type | Description |
| - | - | - |
| `endpoint_selectors` | List\ | the list of cel expressions that filter the k8s bound endpoints for this Operator |
| `csr` | string | CSR is supplied during initial creation to enable creating a mutual TLS secured connection between ngrok and the Operator. This is an internal implementation detail and subject to change. |
| `ingress_endpoint` | string | the public ingress endpoint for this Kubernetes Operator |
#### KubernetesOperatorDeploymentUpdate parameters
| Name | Type | Description |
| - | - | - |
| `name` | string | the deployment name |
| `version` | string | the version of this Kubernetes Operator |
### Response
Returns a 200 response on success
#### Example Response
```json theme={null}
{
"binding": {
"cert": {
"cert": "",
"not_after": "0001-01-01T00:00:00Z",
"not_before": "0001-01-01T00:00:00Z"
},
"endpoint_selectors": null,
"ingress_endpoint": "connect.ngrok-endpoints.com:443"
},
"created_at": "2025-09-04T10:11:43Z",
"deployment": {
"cluster_name": "",
"name": "ngrok-operator",
"namespace": "ngrok-operator",
"version": ""
},
"description": "Example Kubernetes Operator",
"enabled_features": [
"ingress"
],
"id": "k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT",
"metadata": "{\"environment\": \"production\"}",
"principal": {
"id": "usr_32ELAUA7XkJHRP2DgH2JjDRLp81",
"uri": ""
},
"region": "global",
"updated_at": "2025-09-04T10:11:43Z",
"uri": "https://api.ngrok.com/kubernetes_operators/k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT"
}
```
#### Fields
| Name | Type | Description |
| - | - | - |
| `id` | string | unique identifier for this Kubernetes Operator |
| `uri` | string | URI of this Kubernetes Operator API resource |
| `created_at` | string | timestamp when the Kubernetes Operator was created. RFC 3339 format |
| `updated_at` | string | timestamp when the Kubernetes Operator was last updated. RFC 3339 format |
| `description` | string | human-readable description of this Kubernetes Operator. optional, max 255 bytes. |
| `metadata` | string | arbitrary user-defined machine-readable data of this Kubernetes Operator. optional, max 4096 bytes. |
| `principal` | [Ref](#ref-fields) | the principal who created this Kubernetes Operator |
| `enabled_features` | List\ | features enabled for this Kubernetes Operator. a subset of "bindings", "ingress", and "gateway" |
| `region` | string | the ngrok region in which the ingress for this Operator is served. defaults to "global" |
| `deployment` | [KubernetesOperatorDeployment](#kubernetesoperatordeployment-fields) | information about the deployment of this Kubernetes Operator |
| `binding` | [KubernetesOperatorBinding](#kubernetesoperatorbinding-fields) | information about the Bindings feature of this Kubernetes Operator, if enabled |
#### Ref fields
| Name | Type | Description |
| - | - | - |
| `id` | string | a resource identifier |
| `uri` | string | a uri for locating a resource |
#### KubernetesOperatorDeployment fields
| Name | Type | Description |
| - | - | - |
| `name` | string | the deployment name |
| `namespace` | string | the namespace this Kubernetes Operator is deployed to |
| `version` | string | the version of this Kubernetes Operator |
| `cluster_name` | string | user-given name for the cluster the Kubernetes Operator is deployed to |
#### KubernetesOperatorBinding fields
| Name | Type | Description |
| - | - | - |
| `endpoint_selectors` | List\ | the list of cel expressions that filter the k8s bound endpoints for this Operator |
| `cert` | [KubernetesOperatorCert](#kubernetesoperatorcert-fields) | the binding certificate information |
| `ingress_endpoint` | string | the public ingress endpoint for this Kubernetes Operator |
#### KubernetesOperatorCert fields
| Name | Type | Description |
| - | - | - |
| `cert` | string | the public client certificate generated for this Kubernetes Operator from the CSR supplied when enabling the Bindings feature |
| `not_before` | string | timestamp when the certificate becomes valid. RFC 3339 format |
| `not_after` | string | timestamp when the certificate becomes invalid. RFC 3339 format |
## Delete Kubernetes Operator
Delete a Kubernetes Operator
### Request
DELETE /kubernetes\_operators/\{id}
#### Example Request
```bash theme={null}
curl \
-X DELETE \
-H "Authorization: Bearer {API_KEY}" \
-H "Ngrok-Version: 2" \
https://api.ngrok.com/kubernetes_operators/k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT
```
### Response
Returns a 204 response with no body on success
## Get Kubernetes Operator
Get of a Kubernetes Operator
### Request
GET /kubernetes\_operators/\{id}
#### Example Request
```bash theme={null}
curl \
-X GET \
-H "Authorization: Bearer {API_KEY}" \
-H "Ngrok-Version: 2" \
https://api.ngrok.com/kubernetes_operators/k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT
```
### Response
Returns a 200 response on success
#### Example Response
```json theme={null}
{
"binding": {
"cert": {
"cert": "",
"not_after": "0001-01-01T00:00:00Z",
"not_before": "0001-01-01T00:00:00Z"
},
"endpoint_selectors": null
},
"created_at": "2025-09-04T10:11:43Z",
"deployment": {
"cluster_name": "",
"name": "ngrok-operator",
"namespace": "ngrok-operator",
"version": ""
},
"description": "Example Kubernetes Operator",
"enabled_features": [
"ingress"
],
"id": "k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT",
"metadata": "{\"environment\": \"staging\"}",
"principal": {
"id": "usr_32ELAUA7XkJHRP2DgH2JjDRLp81",
"uri": ""
},
"region": "global",
"updated_at": "2025-09-04T10:11:43Z",
"uri": "https://api.ngrok.com/kubernetes_operators/k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT"
}
```
#### Fields
| Name | Type | Description |
| - | - | - |
| `id` | string | unique identifier for this Kubernetes Operator |
| `uri` | string | URI of this Kubernetes Operator API resource |
| `created_at` | string | timestamp when the Kubernetes Operator was created. RFC 3339 format |
| `updated_at` | string | timestamp when the Kubernetes Operator was last updated. RFC 3339 format |
| `description` | string | human-readable description of this Kubernetes Operator. optional, max 255 bytes. |
| `metadata` | string | arbitrary user-defined machine-readable data of this Kubernetes Operator. optional, max 4096 bytes. |
| `principal` | [Ref](#ref-fields) | the principal who created this Kubernetes Operator |
| `enabled_features` | List\ | features enabled for this Kubernetes Operator. a subset of "bindings", "ingress", and "gateway" |
| `region` | string | the ngrok region in which the ingress for this Operator is served. defaults to "global" |
| `deployment` | [KubernetesOperatorDeployment](#kubernetesoperatordeployment-fields) | information about the deployment of this Kubernetes Operator |
| `binding` | [KubernetesOperatorBinding](#kubernetesoperatorbinding-fields) | information about the Bindings feature of this Kubernetes Operator, if enabled |
#### Ref fields
| Name | Type | Description |
| - | - | - |
| `id` | string | a resource identifier |
| `uri` | string | a uri for locating a resource |
#### KubernetesOperatorDeployment fields
| Name | Type | Description |
| - | - | - |
| `name` | string | the deployment name |
| `namespace` | string | the namespace this Kubernetes Operator is deployed to |
| `version` | string | the version of this Kubernetes Operator |
| `cluster_name` | string | user-given name for the cluster the Kubernetes Operator is deployed to |
#### KubernetesOperatorBinding fields
| Name | Type | Description |
| - | - | - |
| `endpoint_selectors` | List\ | the list of cel expressions that filter the k8s bound endpoints for this Operator |
| `cert` | [KubernetesOperatorCert](#kubernetesoperatorcert-fields) | the binding certificate information |
| `ingress_endpoint` | string | the public ingress endpoint for this Kubernetes Operator |
#### KubernetesOperatorCert fields
| Name | Type | Description |
| - | - | - |
| `cert` | string | the public client certificate generated for this Kubernetes Operator from the CSR supplied when enabling the Bindings feature |
| `not_before` | string | timestamp when the certificate becomes valid. RFC 3339 format |
| `not_after` | string | timestamp when the certificate becomes invalid. RFC 3339 format |
## List Kubernetes operators
List all Kubernetes Operators owned by this account
### Request
GET /kubernetes\_operators
#### Example Request
```bash theme={null}
curl \
-X GET \
-H "Authorization: Bearer {API_KEY}" \
-H "Ngrok-Version: 2" \
https://api.ngrok.com/kubernetes_operators
```
### Response
Returns a 200 response on success
#### Example Response
```json theme={null}
{
"next_page_uri": null,
"operators": [
{
"binding": {
"cert": {
"cert": "",
"not_after": "0001-01-01T00:00:00Z",
"not_before": "0001-01-01T00:00:00Z"
},
"endpoint_selectors": null
},
"created_at": "2025-09-04T10:11:43Z",
"deployment": {
"cluster_name": "",
"name": "ngrok-operator",
"namespace": "ngrok-operator",
"version": ""
},
"description": "Example Kubernetes Operator",
"enabled_features": [
"ingress"
],
"id": "k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT",
"metadata": "{\"environment\": \"staging\"}",
"principal": {
"id": "usr_32ELAUA7XkJHRP2DgH2JjDRLp81",
"uri": ""
},
"region": "global",
"updated_at": "2025-09-04T10:11:43Z",
"uri": "https://api.ngrok.com/kubernetes_operators/k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT"
}
],
"uri": "https://api.ngrok.com/kubernetes_operators"
}
```
#### Fields
| Name | Type | Description |
| - | - | - |
| `operators` | [KubernetesOperator](#kubernetesoperator-fields) | the list of Kubernetes Operators for this account |
| `uri` | string | |
| `next_page_uri` | string | URI of the next page, or null if there is no next page |
#### KubernetesOperator fields
| Name | Type | Description |
| - | - | - |
| `id` | string | unique identifier for this Kubernetes Operator |
| `uri` | string | URI of this Kubernetes Operator API resource |
| `created_at` | string | timestamp when the Kubernetes Operator was created. RFC 3339 format |
| `updated_at` | string | timestamp when the Kubernetes Operator was last updated. RFC 3339 format |
| `description` | string | human-readable description of this Kubernetes Operator. optional, max 255 bytes. |
| `metadata` | string | arbitrary user-defined machine-readable data of this Kubernetes Operator. optional, max 4096 bytes. |
| `principal` | [Ref](#ref-fields) | the principal who created this Kubernetes Operator |
| `enabled_features` | List\ | features enabled for this Kubernetes Operator. a subset of "bindings", "ingress", and "gateway" |
| `region` | string | the ngrok region in which the ingress for this Operator is served. defaults to "global" |
| `deployment` | [KubernetesOperatorDeployment](#kubernetesoperatordeployment-fields) | information about the deployment of this Kubernetes Operator |
| `binding` | [KubernetesOperatorBinding](#kubernetesoperatorbinding-fields) | information about the Bindings feature of this Kubernetes Operator, if enabled |
#### Ref fields
| Name | Type | Description |
| - | - | - |
| `id` | string | a resource identifier |
| `uri` | string | a uri for locating a resource |
#### KubernetesOperatorDeployment fields
| Name | Type | Description |
| - | - | - |
| `name` | string | the deployment name |
| `namespace` | string | the namespace this Kubernetes Operator is deployed to |
| `version` | string | the version of this Kubernetes Operator |
| `cluster_name` | string | user-given name for the cluster the Kubernetes Operator is deployed to |
#### KubernetesOperatorBinding fields
| Name | Type | Description |
| - | - | - |
| `endpoint_selectors` | List\ | the list of cel expressions that filter the k8s bound endpoints for this Operator |
| `cert` | [KubernetesOperatorCert](#kubernetesoperatorcert-fields) | the binding certificate information |
| `ingress_endpoint` | string | the public ingress endpoint for this Kubernetes Operator |
#### KubernetesOperatorCert fields
| Name | Type | Description |
| - | - | - |
| `cert` | string | the public client certificate generated for this Kubernetes Operator from the CSR supplied when enabling the Bindings feature |
| `not_before` | string | timestamp when the certificate becomes valid. RFC 3339 format |
| `not_after` | string | timestamp when the certificate becomes invalid. RFC 3339 format |
## GetBoundEndpoints Kubernetes Operator
List Endpoints bound to a Kubernetes Operator
### Request
GET /kubernetes\_operators/\{id}/bound\_endpoints
#### Example Request
```bash theme={null}
curl \
-X GET \
-H "Authorization: Bearer {API_KEY}" \
-H "Ngrok-Version: 2" \
https://api.ngrok.com/kubernetes_operators/k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT/bound_endpoints
```
### Response
Returns a 200 response on success
#### Example Response
```json theme={null}
{
"endpoints": [],
"next_page_uri": null,
"uri": "https://api.ngrok.com/kubernetes_operators/k8sop_32ELIMnXLu9Qkpj1OddUYoLIHfT/bound_endpoints"
}
```
#### Fields
| Name | Type | Description |
| - | - | - |
| `endpoints` | [Endpoint](#endpoint-fields) | the list of all active endpoints on this account |
| `uri` | string | URI of the endpoints list API resource |
| `next_page_uri` | string | URI of the next page, or null if there is no next page |
#### Endpoint fields
| Name | Type | Description |
| - | - | - |
| `id` | string | unique endpoint resource identifier |
| `region` | string | identifier of the region this endpoint belongs to |
| `created_at` | string | timestamp when the endpoint was created in RFC 3339 format |
| `updated_at` | string | timestamp when the endpoint was updated in RFC 3339 format |
| `public_url` | string | URL of the hostport served by this endpoint |
| `proto` | string | protocol served by this endpoint. one of `http`, `https`, `tcp`, or `tls` |
| `scheme` | string | |
| `hostport` | string | hostport served by this endpoint (hostname:port) -> soon to be deprecated |
| `host` | string | |
| `port` | int64 | |
| `type` | string | whether the endpoint is `ephemeral` (served directly by an agent-initiated tunnel) or `edge` (served by an edge) or `cloud (represents a Cloud Endpoint)` |
| `metadata` | string | user-supplied metadata of the associated tunnel or edge object |
| `description` | string | user-supplied description of the associated tunnel |
| `domain` | [Ref](#ref-fields) | the domain reserved for this endpoint |
| `tcp_addr` | [Ref](#ref-fields) | the address reserved for this endpoint |
| `tunnel` | [Ref](#ref-fields) | the tunnel serving requests to this endpoint, if this is an ephemeral endpoint |
| `edge` | [Ref](#ref-fields) | the edge serving requests to this endpoint, if this is an edge endpoint |
| `upstream_url` | string | the local address the tunnel forwards to |
| `upstream_protocol` | string | the protocol the agent uses to forward with |
| `url` | string | the URL of the endpoint |
| `principal` | [Ref](#ref-fields) | The ID of the owner (bot or user) that owns this endpoint |
| `traffic_policy` | string | The Traffic Policy attached to this endpoint |
| `bindings` | List\ | the bindings associated with this endpoint |
| `tunnel_session` | [Ref](#ref-fields) | The tunnel session of the agent for this endpoint |
| `uri` | string | URI of the clep API resource |
| `name` | string | user supplied name for the endpoint |
| `pooling_enabled` | boolean | whether the endpoint allows pooling |
#### Ref fields
| Name | Type | Description |
| - | - | - |
| `id` | string | a resource identifier |
| `uri` | string | a uri for locating a resource |
# Create
Source: https://ngrok.com/docs/api-reference/reservedaddrs/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /reserved_addrs
Create a new reserved address.
# Delete
Source: https://ngrok.com/docs/api-reference/reservedaddrs/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /reserved_addrs/{id}
Delete a reserved address.
# Get
Source: https://ngrok.com/docs/api-reference/reservedaddrs/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /reserved_addrs/{id}
Get the details of a reserved address.
# List
Source: https://ngrok.com/docs/api-reference/reservedaddrs/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /reserved_addrs
List all reserved addresses on this account.
# Update
Source: https://ngrok.com/docs/api-reference/reservedaddrs/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /reserved_addrs/{id}
Update the attributes of a reserved address.
# Create
Source: https://ngrok.com/docs/api-reference/reserveddomains/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /reserved_domains
Create a new reserved domain.
# Delete
Source: https://ngrok.com/docs/api-reference/reserveddomains/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /reserved_domains/{id}
Delete a reserved domain.
# DeleteCertificate
Source: https://ngrok.com/docs/api-reference/reserveddomains/deletecertificate
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /reserved_domains/{id}/certificate
Detach the certificate attached to a reserved domain.
# DeleteCertificateManagementPolicy
Source: https://ngrok.com/docs/api-reference/reserveddomains/deletecertificatemanagementpolicy
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /reserved_domains/{id}/certificate_management_policy
Detach the certificate management policy attached to a reserved domain.
# Get
Source: https://ngrok.com/docs/api-reference/reserveddomains/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /reserved_domains/{id}
Get the details of a reserved domain.
# List
Source: https://ngrok.com/docs/api-reference/reserveddomains/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /reserved_domains
List all reserved domains on this account.
# Update
Source: https://ngrok.com/docs/api-reference/reserveddomains/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /reserved_domains/{id}
Update the attributes of a reserved domain.
# Create
Source: https://ngrok.com/docs/api-reference/secrets/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /vault_secrets
Create a new Secret
# Delete
Source: https://ngrok.com/docs/api-reference/secrets/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /vault_secrets/{id}
Delete a Secret
# Get
Source: https://ngrok.com/docs/api-reference/secrets/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /vault_secrets/{id}
Get a Secret by ID
# List
Source: https://ngrok.com/docs/api-reference/secrets/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /vault_secrets
List all Secrets owned by account
# Update
Source: https://ngrok.com/docs/api-reference/secrets/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /vault_secrets/{id}
Update an existing Secret by ID
# Service Users (Bot Users)
Source: https://ngrok.com/docs/api-reference/service-users
Service Users API reference.
Service Users were previously called Bot Users.
The Bot User API endpoint is still available but will be deprecated in the future.
If you need the Bot Users API reference, you can find it [here](/docs/api-reference/botusers/get).
## Create Service User
Create a new Service User.
### Request
`POST /service_users`
#### Example request
```bash theme={null}
curl \
-X POST \
-H "Authorization: Bearer {API_KEY}" \
-H "Content-Type: application/json" \
-H "Ngrok-Version: 2" \
-d '{"name":"new service user from API"}' \
https://api.ngrok.com/service_users
```
#### Parameters
| Name | Type | Description |
| - | - | - |
| `name` | string | Human-readable name used to identify the Service User. |
| `active` | boolean | Whether or not the Service User is active. |
### Response
Returns a 201 response on success.
#### Example response
```json theme={null}
{
"active": true,
"created_at": "2025-09-04T10:11:43Z",
"id": "service_32ELIFubEAAGUeRtreNW6kr94Od",
"name": "new service user from API",
"uri": "https://api.ngrok.com/service_users/service_32ELIFubEAAGUeRtreNW6kr94Od"
}
```
#### Fields
| Name | Type | Description |
| - | - | - |
| `id` | string | Unique API key resource identifier. |
| `uri` | string | URI to the API resource of this Service User |
| `name` | string | Human-readable name used to identify the Service User. |
| `active` | boolean | Whether or not the Service User is active. |
| `created_at` | string | Timestamp when the API key was created, in RFC 3339 format. |
## Delete Service User
Delete a Service User by ID.
### Request
`DELETE /service_users/\{id\}`
#### Example request
```bash theme={null}
curl \
-X DELETE \
-H "Authorization: Bearer {API_KEY}" \
-H "Ngrok-Version: 2" \
https://api.ngrok.com/service_users/service_32ELIFubEAAGUeRtreNW6kr94Od
```
### Response
Returns a 204 response with no body on success.
## Get Service User
Get the details of a Service User by ID.
### Request
`GET /service_users/\{id\}`
#### Example request
```bash theme={null}
curl \
-X GET \
-H "Authorization: Bearer {API_KEY}" \
-H "Ngrok-Version: 2" \
https://api.ngrok.com/service_users/service_32ELIFubEAAGUeRtreNW6kr94Od
```
### Response
Returns a 200 response on success.
#### Example response
```json theme={null}
{
"active": true,
"created_at": "2025-09-04T10:11:43Z",
"id": "service_32ELIFubEAAGUeRtreNW6kr94Od",
"name": "new service user from API",
"uri": "https://api.ngrok.com/service_users/service_32ELIFubEAAGUeRtreNW6kr94Od"
}
```
#### Fields
| Name | Type | Description |
| - | - | - |
| `id` | string | Unique API key resource identifier. |
| `uri` | string | URI to the API resource of this Service User. |
| `name` | string | Human-readable name used to identify the Service User. |
| `active` | boolean | Whether or not the Service User is active. |
| `created_at` | string | Timestamp when the API key was created, in RFC 3339 format. |
## List Service Users
List all Service Users in this account.
### Request
`GET /service_users`
#### Example request
```bash theme={null}
curl \
-X GET \
-H "Authorization: Bearer {API_KEY}" \
-H "Ngrok-Version: 2" \
https://api.ngrok.com/service_users?limit=1
```
### Response
Returns a 200 response on success.
#### Example response
```json theme={null}
{
"service_users": [
{
"active": true,
"created_at": "2025-09-04T10:11:43Z",
"id": "service_32ELIKFMeMYDQm0tERqc5MmICl4",
"name": "API example service user",
"uri": "https://api.ngrok.com/service_users/service_32ELIKFMeMYDQm0tERqc5MmICl4"
}
],
"next_page_uri": "https://api.ngrok.com/service_users?before_id=service_32ELIKFMeMYDQm0tERqc5MmICl4&limit=1",
"uri": "https://api.ngrok.com/service_users"
}
```
#### Fields
| Name | Type | Description |
| - | - | - |
| `service_users` | [ServiceUser](#serviceuser-fields) | List of all Service Users on this account. |
| `uri` | string | URI of the Service Users list API resource. |
| `next_page_uri` | string | URI of the next page, or null if there is no next page. |
#### ServiceUser fields
| Name | Type | Description |
| - | - | - |
| `id` | string | Unique API key resource identifier. |
| `uri` | string | URI to the API resource of this Service User. |
| `name` | string | Human-readable name used to identify the Service User. |
| `active` | boolean | Whether or not the Service User is active. |
| `created_at` | string | Timestamp when the API key was created, in RFC 3339 format. |
## Update Service User
Update attributes of a Service User by ID.
### Request
`PATCH /service_users/\{id\}`
#### Example request
```bash theme={null}
curl \
-X PATCH \
-H "Authorization: Bearer {API_KEY}" \
-H "Content-Type: application/json" \
-H "Ngrok-Version: 2" \
-d '{"active":false,"name":"inactive service user from API"}' \
https://api.ngrok.com/service_users/service_32ELIFubEAAGUeRtreNW6kr94Od
```
#### Parameters
| Name | Type | Description |
| - | - | - |
| `id` | string | |
| `name` | string | Human-readable name used to identify the Service User. |
| `active` | boolean | Whether or not the Service User is active. |
### Response
Returns a 200 response and a copy of the updated entity on success.
#### Example response
```json theme={null}
{
"active": false,
"created_at": "2025-09-04T10:11:43Z",
"id": "service_32ELIFubEAAGUeRtreNW6kr94Od",
"name": "inactive service user from API",
"uri": "https://api.ngrok.com/service_users/service_32ELIFubEAAGUeRtreNW6kr94Od"
}
```
#### Fields
| Name | Type | Description |
| - | - | - |
| `id` | string | Unique API key resource identifier. |
| `uri` | string | URI to the API resource of this Service User. |
| `name` | string | Human-readable name used to identify the Service User. |
| `active` | boolean | Whether or not the Service User is active. |
| `created_at` | string | Timestamp when the API key was created, in RFC 3339 format. |
# Create
Source: https://ngrok.com/docs/api-reference/sshcertificateauthorities/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /ssh_certificate_authorities
Create a new SSH Certificate Authority
# Delete
Source: https://ngrok.com/docs/api-reference/sshcertificateauthorities/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /ssh_certificate_authorities/{id}
Delete an SSH Certificate Authority
# Get
Source: https://ngrok.com/docs/api-reference/sshcertificateauthorities/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ssh_certificate_authorities/{id}
Get detailed information about an SSH Certificate Authority
# List
Source: https://ngrok.com/docs/api-reference/sshcertificateauthorities/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ssh_certificate_authorities
List all SSH Certificate Authorities on this account
# Update
Source: https://ngrok.com/docs/api-reference/sshcertificateauthorities/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /ssh_certificate_authorities/{id}
Update an SSH Certificate Authority
# Create
Source: https://ngrok.com/docs/api-reference/sshcredentials/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /ssh_credentials
Create a new ssh_credential from an uploaded public SSH key. This ssh credential can be used to start new tunnels via ngrok's SSH gateway.
# Delete
Source: https://ngrok.com/docs/api-reference/sshcredentials/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /ssh_credentials/{id}
Delete an ssh_credential by ID
# Get
Source: https://ngrok.com/docs/api-reference/sshcredentials/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ssh_credentials/{id}
Get detailed information about an ssh_credential
# List
Source: https://ngrok.com/docs/api-reference/sshcredentials/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ssh_credentials
List all ssh credentials on this account
# Update
Source: https://ngrok.com/docs/api-reference/sshcredentials/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /ssh_credentials/{id}
Update attributes of an ssh_credential by ID
# Create
Source: https://ngrok.com/docs/api-reference/sshhostcertificates/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /ssh_host_certificates
Create a new SSH Host Certificate
# Delete
Source: https://ngrok.com/docs/api-reference/sshhostcertificates/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /ssh_host_certificates/{id}
Delete an SSH Host Certificate
# Get
Source: https://ngrok.com/docs/api-reference/sshhostcertificates/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ssh_host_certificates/{id}
Get detailed information about an SSH Host Certificate
# List
Source: https://ngrok.com/docs/api-reference/sshhostcertificates/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ssh_host_certificates
List all SSH Host Certificates issued on this account
# Update
Source: https://ngrok.com/docs/api-reference/sshhostcertificates/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /ssh_host_certificates/{id}
Update an SSH Host Certificate
# Create
Source: https://ngrok.com/docs/api-reference/sshusercertificates/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /ssh_user_certificates
Create a new SSH User Certificate
# Delete
Source: https://ngrok.com/docs/api-reference/sshusercertificates/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /ssh_user_certificates/{id}
Delete an SSH User Certificate
# Get
Source: https://ngrok.com/docs/api-reference/sshusercertificates/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ssh_user_certificates/{id}
Get detailed information about an SSH User Certificate
# List
Source: https://ngrok.com/docs/api-reference/sshusercertificates/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /ssh_user_certificates
List all SSH User Certificates issued on this account
# Update
Source: https://ngrok.com/docs/api-reference/sshusercertificates/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /ssh_user_certificates/{id}
Update an SSH User Certificate
# Create
Source: https://ngrok.com/docs/api-reference/staticbackends/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /backends/static
Create a new static backend
# Delete
Source: https://ngrok.com/docs/api-reference/staticbackends/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /backends/static/{id}
Delete a static backend by ID.
# Get
Source: https://ngrok.com/docs/api-reference/staticbackends/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /backends/static/{id}
Get detailed information about a static backend by ID
# List
Source: https://ngrok.com/docs/api-reference/staticbackends/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /backends/static
List all static backends on this account
# Update
Source: https://ngrok.com/docs/api-reference/staticbackends/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /backends/static/{id}
Update static backend by ID
# Delete
Source: https://ngrok.com/docs/api-reference/tcpedgebackendmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/tcp/{id}/backend
# Get
Source: https://ngrok.com/docs/api-reference/tcpedgebackendmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tcp/{id}/backend
# Replace
Source: https://ngrok.com/docs/api-reference/tcpedgebackendmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/tcp/{id}/backend
# Delete
Source: https://ngrok.com/docs/api-reference/tcpedgeiprestrictionmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/tcp/{id}/ip_restriction
# Get
Source: https://ngrok.com/docs/api-reference/tcpedgeiprestrictionmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tcp/{id}/ip_restriction
# Replace
Source: https://ngrok.com/docs/api-reference/tcpedgeiprestrictionmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/tcp/{id}/ip_restriction
# Delete
Source: https://ngrok.com/docs/api-reference/tcpedgetrafficpolicymodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/tcp/{id}/traffic_policy
# Get
Source: https://ngrok.com/docs/api-reference/tcpedgetrafficpolicymodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tcp/{id}/traffic_policy
# Replace
Source: https://ngrok.com/docs/api-reference/tcpedgetrafficpolicymodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/tcp/{id}/traffic_policy
# Create
Source: https://ngrok.com/docs/api-reference/tlscertificates/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /tls_certificates
Upload a new TLS certificate
# Delete
Source: https://ngrok.com/docs/api-reference/tlscertificates/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /tls_certificates/{id}
Delete a TLS certificate
# Get
Source: https://ngrok.com/docs/api-reference/tlscertificates/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /tls_certificates/{id}
Get detailed information about a TLS certificate
# List
Source: https://ngrok.com/docs/api-reference/tlscertificates/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /tls_certificates
List all TLS certificates on this account
# Update
Source: https://ngrok.com/docs/api-reference/tlscertificates/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /tls_certificates/{id}
Update attributes of a TLS Certificate by ID
# Delete
Source: https://ngrok.com/docs/api-reference/tlsedgebackendmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/tls/{id}/backend
# Get
Source: https://ngrok.com/docs/api-reference/tlsedgebackendmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tls/{id}/backend
# Replace
Source: https://ngrok.com/docs/api-reference/tlsedgebackendmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/tls/{id}/backend
# Delete
Source: https://ngrok.com/docs/api-reference/tlsedgeiprestrictionmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/tls/{id}/ip_restriction
# Get
Source: https://ngrok.com/docs/api-reference/tlsedgeiprestrictionmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tls/{id}/ip_restriction
# Replace
Source: https://ngrok.com/docs/api-reference/tlsedgeiprestrictionmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/tls/{id}/ip_restriction
# Delete
Source: https://ngrok.com/docs/api-reference/tlsedgemutualtlsmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/tls/{id}/mutual_tls
# Get
Source: https://ngrok.com/docs/api-reference/tlsedgemutualtlsmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tls/{id}/mutual_tls
# Replace
Source: https://ngrok.com/docs/api-reference/tlsedgemutualtlsmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/tls/{id}/mutual_tls
# Delete
Source: https://ngrok.com/docs/api-reference/tlsedgetlsterminationmodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/tls/{id}/tls_termination
# Get
Source: https://ngrok.com/docs/api-reference/tlsedgetlsterminationmodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tls/{id}/tls_termination
# Replace
Source: https://ngrok.com/docs/api-reference/tlsedgetlsterminationmodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/tls/{id}/tls_termination
# Delete
Source: https://ngrok.com/docs/api-reference/tlsedgetrafficpolicymodule/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /edges/tls/{id}/traffic_policy
# Get
Source: https://ngrok.com/docs/api-reference/tlsedgetrafficpolicymodule/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /edges/tls/{id}/traffic_policy
# Replace
Source: https://ngrok.com/docs/api-reference/tlsedgetrafficpolicymodule/replace
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml put /edges/tls/{id}/traffic_policy
# Create
Source: https://ngrok.com/docs/api-reference/tunnelgroupbackends/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /backends/tunnel_group
Create a new TunnelGroup backend
# Delete
Source: https://ngrok.com/docs/api-reference/tunnelgroupbackends/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /backends/tunnel_group/{id}
Delete a TunnelGroup backend by ID.
# Get
Source: https://ngrok.com/docs/api-reference/tunnelgroupbackends/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /backends/tunnel_group/{id}
Get detailed information about a TunnelGroup backend by ID
# List
Source: https://ngrok.com/docs/api-reference/tunnelgroupbackends/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /backends/tunnel_group
List all TunnelGroup backends on this account
# Update
Source: https://ngrok.com/docs/api-reference/tunnelgroupbackends/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /backends/tunnel_group/{id}
Update TunnelGroup backend by ID
# Get
Source: https://ngrok.com/docs/api-reference/tunnels/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /tunnels/{id}
Get the status of a tunnel by ID
# List
Source: https://ngrok.com/docs/api-reference/tunnels/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /tunnels
List all online tunnels currently running on the account.
# Get
Source: https://ngrok.com/docs/api-reference/tunnelsessions/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /tunnel_sessions/{id}
Get the detailed status of a tunnel session by ID
# List
Source: https://ngrok.com/docs/api-reference/tunnelsessions/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /tunnel_sessions
List all online tunnel sessions running on this account.
# Restart
Source: https://ngrok.com/docs/api-reference/tunnelsessions/restart
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /tunnel_sessions/{id}/restart
Issues a command instructing the ngrok agent to restart. The agent restarts itself by calling exec() on platforms that support it. This operation is notably not supported on Windows. When an agent restarts, it reconnects with a new tunnel session ID.
# Stop
Source: https://ngrok.com/docs/api-reference/tunnelsessions/stop
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /tunnel_sessions/{id}/stop
Issues a command instructing the ngrok agent that started this tunnel session to exit.
# Update
Source: https://ngrok.com/docs/api-reference/tunnelsessions/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /tunnel_sessions/{id}/update
Issues a command instructing the ngrok agent to update itself to the latest version. After this call completes successfully, the ngrok agent will be in the update process. A caller should wait some amount of time to allow the update to complete (at least 10 seconds) before making a call to the Restart endpoint to request that the agent restart itself to start using the new code. This call will never update an ngrok agent to a new major version which could cause breaking compatibility issues. If you wish to update to a new major version, that must be done manually. Still, please be aware that updating your ngrok agent could break your integration. This call will fail in any of the following circumstances: there is no update available the ngrok agent's configuration disabled update checks the agent is currently in process of updating the agent has already successfully updated but has not yet been restarted
# Create
Source: https://ngrok.com/docs/api-reference/vaults/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /vaults
Create a new Vault
# Delete
Source: https://ngrok.com/docs/api-reference/vaults/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /vaults/{id}
Delete a Vault
# Get
Source: https://ngrok.com/docs/api-reference/vaults/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /vaults/{id}
Get a Vault by ID
# List
Source: https://ngrok.com/docs/api-reference/vaults/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /vaults
List all Vaults owned by account
# Update
Source: https://ngrok.com/docs/api-reference/vaults/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /vaults/{id}
Update an existing Vault by ID
# Create
Source: https://ngrok.com/docs/api-reference/weightedbackends/create
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml post /backends/weighted
Create a new Weighted backend
# Delete
Source: https://ngrok.com/docs/api-reference/weightedbackends/delete
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml delete /backends/weighted/{id}
Delete a Weighted backend by ID.
# Get
Source: https://ngrok.com/docs/api-reference/weightedbackends/get
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /backends/weighted/{id}
Get detailed information about a Weighted backend by ID
# List
Source: https://ngrok.com/docs/api-reference/weightedbackends/list
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml get /backends/weighted
List all Weighted backends on this account
# Update
Source: https://ngrok.com/docs/api-reference/weightedbackends/update
https://raw.githubusercontent.com/ngrok/ngrok-openapi/refs/heads/main/ngrok.yaml patch /backends/weighted/{id}
Update Weighted backend by ID
# API Filtering
Source: https://ngrok.com/docs/api/api-filtering
Learn how to use API Filtering to make operational tooling faster and more precise.
When using ngrok's API, you can add the `filter` query parameter to `GET` requests to return only those results which match a provided criteria. This makes automated management of resources easier while eliminating the need to download large collections and filter client-side.
To use API Filtering, you pass a subset of CEL expressions to the `filter` query parameter, as demonstrated in the following example.
This example request fetches a list of all your Cloud and Agent endpoints.
```http theme={null}
GET /endpoints?filter=obj.type == "cloud" || obj.type == "agent"
```
## Request shape
```http theme={null}
GET /{resource}?filter={CEL_EXPRESSION}
```
### cURL usage
```
curl --location 'https://api.ngrok.com/endpoints' \
--get \
--data-urlencode '' \
--header 'Ngrok-Version: 2' \
--header 'Authorization: Bearer '
```
## Supported CEL (subset)
These core operators and helpers are supported:
* Logical operators: `!`, `&&`, `||`
* Comparative operators: `<`, `<=`, `==`, `!=`, `>=`, `>`
* Parentheses for grouping
* List membership using the `in` keyword
* String substring checks: `startsWith()`, `contains()`, `endsWith()`
* Length / emptiness checks: `size()`, `== ""`, `== null`
* Date and time helpers: `timestamp(RFC-3339)`, `timestamp(time.now)`, `timestamp(time.now).subtract()`, `timestamp(time.now).add()`
### Instance inspection (versus list comprehension)
Expressions are evaluated against a single **resource instance** exposed as `obj`. Compare fields **on the instance** rather than attempting list-wise checks on fields.
✅ Valid
```http theme={null}
GET /endpoints?filter=obj.type == "cloud" || obj.type == "agent"
GET /endpoints?filter=obj.type in ["agent", "cloud"]
GET /endpoints?filter="public" in obj.bindings || "internal" in obj.bindings
```
❌ Not valid
```http theme={null}
GET /endpoints?filter=["agent","cloud"] in obj.types
GET /endpoints?filter=obj.bindings in ["public", "internal"]
```
## Dates and time helpers
* **Treat timestamps as numerics** by using `<`, `<=`, `==`, `>=`, `>` directly on `timestamp()` fields, for example:
```http theme={null}
GET /vaults?filter=obj.created_at < timestamp("2025-10-31T09:23:45-07:00")
```
* **Relative helpers based on the current time:** Use `timestamp(time.now)` for the current time, then chain `.subtract()` or `.add()` with a duration string such as `"7d"`, `"24h"`, or `"15m"`. For example:
```http theme={null}
# resources created in the last 7 days
GET /endpoints?filter=obj.created_at >= timestamp(time.now).subtract("7d")
# resources that will expire within the next 24 hours
GET /tls_certificates?filter=obj.not_after <= timestamp(time.now).add("24h")
```
## Query restrictions and limitations
### Unsupported CEL features
To keep filter evaluation small and predictable, the following CEL features are not supported.
* **No index access** (for example, `a[0]`)
* **No arithmetic** (for example, `a + b`)
* **No ternary** (for example, `cond ? x : y`)
* **No type checks** (for example, `type(a) == string`)
* **No regexes**
* **No fuzzy matching**
These exclusions intentionally keep evaluation small and predictable.
### High-entropy fields and substring checks
**High entropy** fields are fields with values that are effectively random, usually because they're generated. The `id` field on a response object, such as `obj.id`, is a common example.
[Substring functions](https://github.com/google/cel-spec/blob/master/doc/langdef.md#string-functions), such as `startsWith()`, `contains()`, and `endsWith()`, are **disallowed** on high entropy fields. Check for equality on these fields instead. For example:
```
obj.id == "ep_123"
```
### Query complexity (budgeting/limits)
Very large expressions can stress the query engine. The service may enforce **limits on the number of conditions per query** or similar throttles in the future.
## Filterable resources and fields
The initial release prioritizes the resource types and fields below. CEL filtering is not supported on deprecated endpoints. Field coverage is evolving and may change before GA.
| Resource Type | Filterable Fields |
| - | - |
| **Endpoints** | - `id`
- `created_at`
- `description`
- `metadata`
- `principal.id`
- `type`
- `binding`
- `url`
- `pooling_enabled`
- `scheme`
- `region`
- `name` |
| **Reserved Addresses** | - `id`
- `created_at`
- `description`
- `metadata`
- `addr`
- `region` |
| **Reserved Domains** | - `id`
- `created_at`
- `description`
- `metadata`
- `domain`
- `region`
- `cname_target`
- `certificate.id`
- `acme_challenge_cname_target` |
| **TLS Certificates** | - `id`
- `created_at`
- `description`
- `metadata`
- `subject_common_name`
- `not_after`
- `not_before`
- `serial_number` |
| **Certificate Authorities** | - `id`
- `created_at`
- `description`
- `metadata`
- `subject_common_name`
- `not_before`
- `not_after` |
| **IP Policies** | - `id`
- `created_at`
- `description`
- `metadata` |
| **IP Policy Rules** | - `id`
- `created_at`
- `description`
- `metadata`
- `ip_policy`
- `cidr`
- `action` |
| **Agent Ingress** | - `id`
- `created_at`
- `description`
- `metadata`
- `domain` |
| **Tunnel Sessions** | - `id`
- `metadata`
- `agent_version`
- `ip`
- `os`
- `region`
- `started_at`
- `credential` |
| **Event Destinations** | - `id`
- `created_at`
- `description`
- `metadata` |
| **Event Subscriptions** | - `id`
- `created_at`
- `description`
- `metadata` |
| **IP Restrictions** | - `id`
- `created_at`
- `description`
- `metadata` |
| **API Keys** | - `id`
- `created_at`
- `description`
- `metadata`
- `owner_id` |
| **SSH Credentials** | - `id`
- `created_at`
- `description`
- `metadata`
- `owner_id`
- `acl` |
| **Credentials** | - `id`
- `created_at`
- `description`
- `metadata`
- `owner_id`
- `acl` |
| **Service Users** | - `id`
- `created_at` |
| **SSH Certificate Authorities** | - `id`
- `created_at`
- `description`
- `metadata` |
| **Vaults** | - `id`
- `created_at`
- `description`
- `metadata`
- `name` |
| **Secrets** | - `id`
- `created_at`
- `description`
- `metadata`
- `name` |
## Usage examples
### **Filter endpoints by type and creation time**
```http theme={null}
GET /endpoints?filter=obj.type == "cloud" && obj.created_at < timestamp("2025-10-31T09:23:45-07:00")
# or using helpers
GET /endpoints?filter=obj.type == "cloud" && obj.created_at >= timestamp(time.now).subtract("6d")
```
Reference:
* [`LIST /endpoints`](/docs/api-reference/endpoints/list)
### **Reserved domains by prefix**
```http theme={null}
GET /reserved_domains?filter=obj.domain.startsWith("myapi.ngrok")
```
Reference:
* [`LIST /reserved_domains`](/docs/api-reference/reserveddomains/list)
### **IP policy rules by CIDR and action**
```http theme={null}
GET /ip_policy_rules?filter=obj.cidr.contains("1.1.0.0/16") && obj.action == "deny"
```
Reference:
* [`LIST /ip_policy_rules`](/docs/api-reference/ippolicyrules/list)
### **Credentials by owner with optional empty ACL**
```http theme={null}
GET /credentials?filter=obj.owner_id == "usr_2tEpN0yrxDI4j8jVnhVRoTNN2Tx" && (obj.acl == null || obj.acl == "")
```
Reference:
* [`LIST /credentials`](/docs/api-reference/credentials/list)
### **Complex nesting**
```http theme={null}
GET /agent_ingresses?filter=obj.domain in ["foo.com","bar.com","baz.com"] || (obj.created_at < timestamp("2025-05-10Z") && obj.description.contains("cowbell"))
```
Reference:
* [`LIST /agent_ingresses`](/docs/api-reference/agentingresses/list)
## Error handling
Invalid filters return **HTTP 400** with a structured error body (`category`, `status_code`, `message`, `details`). Example:
```http theme={null}
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Cache-Control: no-store
{
"error_code": "invalid_cel_expression",
"status_code": 400,
"msg": "Invalid CEL query: unsupported field: endpoint.idk (must be endpoint.url, endpoint.id, endpoint.type, or endpoint.bindings).",
"details": {
"operation_id": "op_k23j45n134jkasdfk34jkjnlkjuhasdf"
}
}
```
# ngrok API Overview
Source: https://ngrok.com/docs/api/index
Learn about the ngrok REST API for programmatic access to all ngrok resources including endpoints, domains, and configurations.
## Overview
The ngrok API provides programmatic access to all of ngrok's resources.
The API is REST-ish. It follows most of the conventions of a REST API but
diverges slightly when the REST model does not fit well.
The API is available at `https://api.ngrok.com`. The API listens only on
port 443 to help avoid any accidental unencrypted requests.
The API is designed to be simple enough to be called with `curl` and HTTP
libraries in your programming language of choice. Other ways to
interact with the API include native API client libraries, a native CLI and a
Terraform Provider.
#### Other ways to interact with the API
* **[Agent API CLI](/docs/gateway/agent/cli-api/)**: Explore and script the API via the `ngrok api` commands included in the ngrok agent.
* **[API Client Libraries](#client-libraries)**: Idiomatic API client libraries are published for all major programming languages
* **[Terraform Provider](#terraform-provider)**: Use ngrok's Terraform provider to manage ngrok resources
#### You may be looking for other programmatic ways to work with ngrok
* **[Agent API](/docs/gateway/agent/api)**: The ngrok agent has its own API if you're trying to dynamically start and stop endpoints and tunnels
* **[Agent SDKs](/docs/agent-sdks/)**: If you're looking to embed ngrok agent functionality as a library in your own software
## Quickstart
Start by [generating a new API key](https://dashboard.ngrok.com/api-keys) in the ngrok Dashboard.
##### Access the API with curl
```
curl https://api.ngrok.com -H "authorization: Bearer {API Key}" -H "ngrok-version: 2"
```
##### Access the API with the Agent CLI
```
ngrok config add-api-key "{API Key}"
ngrok api endpoints list
```
## Client libraries
Open-source API client libraries are published to make working with the ngrok API
feel native and fluent in your favorite programming language. Library
repositories are published in the [ngrok github
organization](https://github.com/ngrok).
| Language | Installation | Documentation | Repository |
| - | - | - | - |
| Go | `go get github.com/ngrok/ngrok-api-go/v4` | [Documentation](https://pkg.go.dev/github.com/ngrok/ngrok-api-go/v4) | [GitHub](https://github.com/ngrok/ngrok-api-go) |
| .NET | `dotnet add package NgrokApi` | [Documentation](https://github.com/ngrok/ngrok-api-dotnet) | [GitHub](https://github.com/ngrok/ngrok-api-dotnet) |
| Ruby | `gem install ngrok-api` | [Documentation](https://ruby-api.docs.ngrok.com) | [GitHub](https://github.com/ngrok/ngrok-api-ruby) |
| Python | `pip install ngrok-api` | [Documentation](https://python-api.docs.ngrok.com) | [GitHub](https://github.com/ngrok/ngrok-api-python) |
| Java (unstable) | See the README for installing with Maven | [Documentation](https://java-api.docs.ngrok.com) | [GitHub](https://github.com/ngrok/ngrok-api-java) |
| Scala (unstable) | See the README for installing with Maven | [Documentation](https://python-api.docs.ngrok.com) | [GitHub](https://github.com/ngrok/ngrok-api-scala) |
## Terraform provider
When you use ngrok resources as part of production infrastructure, it is an
industry best practice to define them using an infrastructure-as-code tool like
[Terraform](https://www.terraform.io/). An official Terraform
provider is published that consumes the ngrok API to manage your resources in this way.
Consult the documentation for the [ngrok Terraform provider on Hashicorp's
Terraform
Registry.](https://registry.terraform.io/providers/ngrok/ngrok/latest/docs)
#### example.tf
```hcl theme={null}
# Configure the ngrok provider
provider "ngrok" {
api_key = "{API_KEY}"
}
# Provision an ngrok domain
resource "ngrok_reserved_domain" "my_domain" {
name = "my-domain.example.com"
region = "us"
certificate_management_policy {
authority = "letsencrypt"
private_key_type = "ecdsa"
}
}
```
## Authentication
| | |
| - | - |
| Base URL | `https://api.ngrok.com` |
| Authentication Header | **`authorization: Bearer {API Key}`** |
Requests to the API must include an API key as a bearer token in the
`Authorization` header.
* **[API Keys on the ngrok dashboard](https://dashboard.ngrok.com/api-keys)**: Provision your first API key from your ngrok dashboard.
* **[API keys API Resource](/docs/api-reference/apikeys/list)**: Once you have an API key, you may provision additional API keys programmatically.
## Content types
Requests to the API with a content body must set a `content-type` header of
`application/json`. All responses returned by the API will use the
`application/json` content type.
## Versioning and API stability
Requests to the API must set the `ngrok-version` header. The latest version is
`2`. All other versions are deprecated.
The ngrok API guarantees that breaking changes to the API will never be made
unless the caller explicitly opts in to a newer version. The following
non-breaking changes to the API may be made to existing versions:
* The addition of new resources
* The addition of new methods to existing resources
* The addition of new fields on existing resource representations
* Bug fixes which change the API to match documented behavior
## Pagination
List endpoints can be paginated using the query parameters `limit` and
`before_id`. Results are returned ordered from newest to oldest. The maximum
value of `limit` is 100. If a limit is not specified, it will default to 100.
If `before_id` is not specified, the first page of results will be returned.
You can provide an explicit value for `before_id` to retrieve items created
before the given ID. Each response to a list request will include a
`next_page_uri` field, which will be the full URL you can request to retrieve
the next page of results. If there are no more results, `next_page_uri` will be
`null`.
## Timestamps and timezones
Timestamp fields in the ngrok API are represented as strings that are returned
in the [RFC 3339 format](https://www.ietf.org/rfc/rfc3339.txt). Timestamps
returned by the API are in UTC time which is indicated by a `Z` at the end.
## Rate limits
The ngrok API enforces a limit on all accounts of 120 requests over a rolling
60 second window. If you exceed the rate limit, ngrok will return
[ERR\_NGROK\_226](/docs/errors/err_ngrok_226) and an HTTP Status Code of 429.
## IP restrictions
All API access requires an API key, but you may also further restrict which IPs
are permitted to make requests to the API. You may define one or more IP
Policies to configure which CIDR blocks may manipulate the API for your
account.
If you use SCIM with an IdP, you may need to add the IPs of your IdP as well
because SCIM requests to the ngrok API are subject to these IP restrictions as
well.
IP Restrictions can be configured manually on the ngrok dashboard or
programmatically via API with a `type` of `api`.
* **[IP Restrictions on your ngrok dashboard](https://dashboard.ngrok.com/ip-restrictions)**
* **[IP Restrictions API Resource](/docs/api-reference/iprestrictions/list/)**
## Errors
It is important to provide a well-defined interface to errors
you encounter when working with the ngrok API. Well-defined error surfaces and codes
are what allow your software to appropriately handle error conditions.
Errors returned by the ngrok API are serialized with the following example format:
```
{
"error_code": "ERR_NGROK_218",
"status_code": 400,
"msg": "Your request has not specified an API version. Please include the version you wish to use in the Ngrok-Version header. Supported versions: 2.",
"details": {
"operation_id": "op_2RfSBcv0nsy71XCHWOegjx1OoKh"
}
}
```
Every error returned by the ngrok API includes a globally unique error code in
the `error_code` property field. This error code is distinct for every possible
error condition that can be encountered so your software can properly handle
different error conditions.
Consult the **[Error Reference Documentation](/docs/errors)** for the complete
list of all error codes returned by ngrok.
## CORS
The ngrok API supports CORS ([Cross Origin Resource
Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)) so that you
may initiate requests to it from Javascript running in a web browser on other
domains.
The response to CORS requests include the `Access-Control-Allow-Origin` and
`Access-Control-Allow-Credentials` headers.
The ngrok API identifies any request with an `OPTIONS` method and the headers
`Origin` and `Access-Control-Request-Method` as a CORS preflight request. The API
responds to CORS preflight requests as follows:
* The API sets the `Access-Control-Allow-Origin` to match the requested `Origin`.
* The API sets `Access-Control-Allow-Methods` to all supported methods for the
requested resource.
* The API echoes back all requested header from
`Access-Control-Request-Headers` in `Access-Control-Allow-Headers`
* The API responds with `Access-Control-Allow-Credentials: true` because the
`Authorization` header is required for accessing API resources.
* The API sets the `Access-Control-Max-Age` header to enable the preflight
response to be cached for up to 10 minutes.
## API pricing
The API is available to all ngrok users at no additional charge. You only incur
costs if the resources provisioned by the API incur a cost.
[API IP Restrictions](#ip-restrictions) is available on the Pay-as-you-go plan.
# Errors
Source: https://ngrok.com/docs/errors/index
## Philosophy
When you encounter an error while using ngrok, we report a globally unique
error code. Each error code corresponds to a specific location in ngrok's code
which helps us quickly identify where something went wrong and help you know
exactly how to fix it.
When your report a bug or email us about a support issue, please include the
unique error code if you have encountered one. It will help us diagnose and
solve your issue much more quickly.
ngrok's error codes were also designed so that you can paste them into your
favorite search engine and immediately find a dedicated page with instructions
on how to fix your problem.
## Programmatic Error Handling
When working with ngrok's programmatically, we return these unique error codes
in a structured way so that you can write software which appropriately handles
different error conditions.
* [API Error Handling](/docs/api/#errors)
## Common Errors
You're more likely to run into some errors than others. The most common are
listed here to help make your troubleshooting easier.
| Code | Message |
| - | - |
| [ERR\_NGROK\_100](/docs/errors/err_ngrok_100) | Invalid metadata length |
| [ERR\_NGROK\_108](/docs/errors/err_ngrok_108) | You've hit your account limit for simultaneous ngrok agent sessions. Try stopping an existing agent or upgrading your account. |
| [ERR\_NGROK\_120](/docs/errors/err_ngrok_120) | Your ngrok agent version `VERSION` is no longer supported. Only the most recent version of the ngrok agent is supported without an account. Update to a newer version with `ngrok update` or by downloading from [https://download.ngrok.com](https://download.ngrok.com). Sign up for an account to avoid forced version upgrades: [https://ngrok.com/signup](https://ngrok.com/signup). |
| [ERR\_NGROK\_1205](/docs/errors/err_ngrok_1205) | You failed to solve the catpcha, please try again. |
| [ERR\_NGROK\_1226](/docs/errors/err_ngrok_1226) | You are disallowed from creating an ngrok account due to violation of the terms of service. |
| [ERR\_NGROK\_3004](/docs/errors/err_ngrok_3004) | ngrok gateway error. The server returned an invalid or incomplete HTTP response. Try starting ngrok with the full upstream service URL (for example, ngrok http [https://localhost:8081](https://localhost:8081)) |
| [ERR\_NGROK\_3200](/docs/errors/err_ngrok_3200) | Tunnel not found. This could be because your agent is not online or your tunnel has been flagged by our automated moderation system. |
| [ERR\_NGROK\_3208](/docs/errors/err_ngrok_3208) | The account associated with this hostname has been banned.We've determined this account to be in violation of ngrok's terms of service.If you are the account owner and believe this is a mistake, please contact [support@ngrok.com](mailto:support@ngrok.com). |
| [ERR\_NGROK\_4011](/docs/errors/err_ngrok_4011) | Your password must be at least 10 characters. |
| [ERR\_NGROK\_4013](/docs/errors/err_ngrok_4013) | You may not create a new account because you are already a member of a free account. Upgrade or delete that account first before creating a new account. |
| [ERR\_NGROK\_4100](/docs/errors/err_ngrok_4100) | The email or password you entered is not valid. |
| [ERR\_NGROK\_4101](/docs/errors/err_ngrok_4101) | A user with the email address already exists. |
| [ERR\_NGROK\_4108](/docs/errors/err_ngrok_4108) | Sign ups are disallowed for the email provider. Please sign up with a different email provider. |
| [ERR\_NGROK\_6022](/docs/errors/err_ngrok_6022) | Before you can serve HTML content, you must sign up for an ngrok account and install your authtoken. |
| [ERR\_NGROK\_6024](/docs/errors/err_ngrok_6024) | You are about to visit `HOSTPORT`, served by `SERVINGIP`. This website is served for free through ngrok.com. You should only visit this website if you trust whoever sent the link to you. |
| [ERR\_NGROK\_8012](/docs/errors/err_ngrok_8012) | Traffic was successfully tunneled to the ngrok agent, but the agent failed to establish a connection to the upstream web service |
## All Errors
Consult the [Errors Reference Documentation](/docs/errors/reference) for a
complete list of all of ngrok's error codes.
## Customize Error Pages for your Traffic
To access and provide feedback on a development preview of custom error pages [Fill out the form](https://ngrok.com/new-features/custom-error-pages?ref=errordoc).
# Errors Reference
Source: https://ngrok.com/docs/errors/reference
Complete reference for all ngrok error codes. Find explanations, causes, and fixes for every ngrok tunnel, agent, and API error in one place.
| Code | Message |
| - | - |
| [ERR\_NGROK\_100](/docs/errors/err_ngrok_100) | Invalid metadata length: `VAL` bytes. Max: `MAX` |
| [ERR\_NGROK\_102](/docs/errors/err_ngrok_102) | The last payment for the `ACCOUNT` account failed. |
| [ERR\_NGROK\_103](/docs/errors/err_ngrok_103) | The account `ACCOUNT` has been suspended. |
| [ERR\_NGROK\_105](/docs/errors/err_ngrok_105) | The authtoken you specified does not look like a proper ngrok authtoken. |
| [ERR\_NGROK\_106](/docs/errors/err_ngrok_106) | The authtoken you specified is an ngrok v1 authtoken, but you're using ngrok v2. |
| [ERR\_NGROK\_107](/docs/errors/err_ngrok_107) | The authtoken you specified is properly formed, but it is invalid. |
| [ERR\_NGROK\_108](/docs/errors/err_ngrok_108) | Your account is limited to `MAX` simultaneous ngrok agent sessions. |
| [ERR\_NGROK\_109](/docs/errors/err_ngrok_109) | The authentication payload you specified is not valid. |
| [ERR\_NGROK\_110](/docs/errors/err_ngrok_110) | The session cookie you specified is not valid. |
| [ERR\_NGROK\_111](/docs/errors/err_ngrok_111) | The heartbeat interval you specified is not valid. |
| [ERR\_NGROK\_112](/docs/errors/err_ngrok_112) | The heartbeat tolerance you specified is not valid. |
| [ERR\_NGROK\_115](/docs/errors/err_ngrok_115) | Your IP `IP` does not match the IP Policies specified by the Agent IP Restriction for this account. Authenticate from an IP in the correct range or update your Agent IP Restrictions from the ngrok dashboard. [https://dashboard.ngrok.com/ip-restrictions](https://dashboard.ngrok.com/ip-restrictions) |
| [ERR\_NGROK\_116](/docs/errors/err_ngrok_116) | Your IP `IP` does not match the IP ACL policy specified for your credentials. Authenticate from an IP in the correct range or make sure you are using the correct credentials |
| [ERR\_NGROK\_118](/docs/errors/err_ngrok_118) | Your account `ACCOUNTNAME` is not permitted to use the ngrok enterprise tunnel ingress. |
| [ERR\_NGROK\_119](/docs/errors/err_ngrok_119) | The agent specified an invalid semantic version string: `VERSION` |
| [ERR\_NGROK\_121](/docs/errors/err_ngrok_121) | Your `PRODUCT` version "`VERSION`" is too old. The minimum supported agent version for your account is "`MINVERSION`". Update to a newer version with 'ngrok update', by downloading from [https://ngrok.com/download](https://ngrok.com/download), or by updating your SDK version. Paid accounts are currently excluded from minimum agent version requirements. To begin handling traffic immediately without updating your agent, upgrade to a paid plan: [https://dashboard.ngrok.com/billing/choose-a-plan](https://dashboard.ngrok.com/billing/choose-a-plan). |
| [ERR\_NGROK\_122](/docs/errors/err_ngrok_122) | Your account is not permitted to use the agent ingress "`DOMAIN`". |
| [ERR\_NGROK\_123](/docs/errors/err_ngrok_123) | The account "`NAME`" may not start an ngrok agent session until the admin's email address is verified. Verify your email at [https://dashboard.ngrok.com/user/settings](https://dashboard.ngrok.com/user/settings) |
| [ERR\_NGROK\_124](/docs/errors/err_ngrok_124) | Your agent provided an invalid UserAgent: `ERR` |
| [ERR\_NGROK\_125](/docs/errors/err_ngrok_125) | The analytics payload you specified is not valid. |
| [ERR\_NGROK\_126](/docs/errors/err_ngrok_126) | The agent ingress "`DOMAIN`" is not available via "`IP`". |
| [ERR\_NGROK\_127](/docs/errors/err_ngrok_127) | Your account is not permitted to use the agent ingress via "`IP`". |
| [ERR\_NGROK\_128](/docs/errors/err_ngrok_128) | Something went wrong. Please try your request again later. |
| [ERR\_NGROK\_200](/docs/errors/err_ngrok_200) | The ngrok API requires that you set the Authorization header for authentication. Your API keys and instructions are available on your dashboard: [https://dashboard.ngrok.com/api-keys](https://dashboard.ngrok.com/api-keys) |
| [ERR\_NGROK\_201](/docs/errors/err_ngrok_201) | The ngrok API requires that you use Basic or Bearer authentication via the Authorization header. It could not parse the header in this request. API keys and instructions are available on your dashboard: [https://dashboard.ngrok.com/api-keys](https://dashboard.ngrok.com/api-keys) |
| [ERR\_NGROK\_202](/docs/errors/err_ngrok_202) | The API authentication you specified does not look like a valid credential. API keys and instructions are available on your dashboard: [https://dashboard.ngrok.com/api-keys](https://dashboard.ngrok.com/api-keys) |
| [ERR\_NGROK\_203](/docs/errors/err_ngrok_203) | The API authentication you specified is properly formed, but it is invalid. API keys and instructions are available on your dashboard: [https://dashboard.ngrok.com/api-keys](https://dashboard.ngrok.com/api-keys) |
| [ERR\_NGROK\_204](/docs/errors/err_ngrok_204) | This is a valid API token, but the account `ACCOUNT` is not allowed to use the ngrok API. |
| [ERR\_NGROK\_205](/docs/errors/err_ngrok_205) | The account `ACCOUNT` has been suspended. This is usually the result of violating the ngrok Terms of Service. Email [support@ngrok.com](mailto:support@ngrok.com) if you think your suspension is an error. |
| [ERR\_NGROK\_206](/docs/errors/err_ngrok_206) | The authentication you specified is actually an authtoken. Check your records for an API key. API keys and instructions are available on your dashboard: [https://dashboard.ngrok.com/api-keys](https://dashboard.ngrok.com/api-keys) |
| [ERR\_NGROK\_207](/docs/errors/err_ngrok_207) | The authentication you specified is actually an authtoken, not an API key token. Your key: `TOKEN`. Check your records for an API key with the form FIRSTPART\_SECONDPART. API keys and instructions are available on your dashboard: [https://dashboard.ngrok.com/api-keys](https://dashboard.ngrok.com/api-keys) |
| [ERR\_NGROK\_208](/docs/errors/err_ngrok_208) | The authentication you specified is actually an API key ID, not an API key token. Your credential: `TOKEN`. Check your records for an API key with the form FIRSTPART\_SECONDPART. API keys and instructions are available on your dashboard: [https://dashboard.ngrok.com/api-keys](https://dashboard.ngrok.com/api-keys) |
| [ERR\_NGROK\_210](/docs/errors/err_ngrok_210) | The content type you specified `CTYPE` is not supported by the API. Check your API client implementation and see the list of supported content types: [https://ngrok.com/docs/api#content-types](https://ngrok.com/docs/api#content-types) |
| [ERR\_NGROK\_211](/docs/errors/err_ngrok_211) | The `METHOD` request you made does not expect a body, but you provided one. Check your API client implementation and review the API documentation: [https://ngrok.com/docs/api-reference/](https://ngrok.com/docs/api-reference/). |
| [ERR\_NGROK\_212](/docs/errors/err_ngrok_212) | The server was unable to read the complete request body. Check your API client implementation and review the API documentation: [https://ngrok.com/docs/api-reference/](https://ngrok.com/docs/api-reference/). |
| [ERR\_NGROK\_213](/docs/errors/err_ngrok_213) | The `CTYPE` request body could not be parsed. Check your API client implementation and review the API documentation: [https://ngrok.com/docs/api-reference/](https://ngrok.com/docs/api-reference/). |
| [ERR\_NGROK\_214](/docs/errors/err_ngrok_214) | The request parameter `NAME` is unknown and not expected. The supported fields are: `SUPPORTED`. Check your API client implementation and review the API documentation: [https://ngrok.com/docs/api-reference/](https://ngrok.com/docs/api-reference/). |
| [ERR\_NGROK\_215](/docs/errors/err_ngrok_215) | The value provided for the request parameter `NAME` is invalid. Check your request and review the API documentation: [https://ngrok.com/docs/api-reference/](https://ngrok.com/docs/api-reference/). |
| [ERR\_NGROK\_216](/docs/errors/err_ngrok_216) | You did not provide a Content-Type with your request. Check your API client implementation and use one of the supported content types: [https://ngrok.com/docs/api#content-types](https://ngrok.com/docs/api#content-types) |
| [ERR\_NGROK\_217](/docs/errors/err_ngrok_217) | The provided API version `VERSION` is invalid or unsupported. Supported versions: `SUPPORTED`. Check your API client implementation. |
| [ERR\_NGROK\_218](/docs/errors/err_ngrok_218) | Your request has not specified an API version. Include the version you wish to use in the Ngrok-Version header. Supported versions: `SUPPORTED`. |
| [ERR\_NGROK\_219](/docs/errors/err_ngrok_219) | `TLSVERSION` is not a supported TLS version. Supported versions: `SUPPORTED`. |
| [ERR\_NGROK\_220](/docs/errors/err_ngrok_220) | Your IP does not match the IP Policy for this Account. Authenticate from an IP in the correct range or update your IP Restrictions from the ngrok dashboard. [https://dashboard.ngrok.com/ip-restrictions](https://dashboard.ngrok.com/ip-restrictions) |
| [ERR\_NGROK\_221](/docs/errors/err_ngrok_221) | This is a valid API token, but the account `ACCOUNT` is not authorized to submit or view abuse reports. Email [support@ngrok.com](mailto:support@ngrok.com) if you believe this is an error. |
| [ERR\_NGROK\_223](/docs/errors/err_ngrok_223) | `ID` is not a valid resource reference identifier. |
| [ERR\_NGROK\_224](/docs/errors/err_ngrok_224) | The value `VAL` is not valid for the terminate\_at property of the TLS Termination endpoint configuration module. Must be either 'edge', 'agent' or 'upstream'. |
| [ERR\_NGROK\_225](/docs/errors/err_ngrok_225) | Your account is limited to `MAX` simultaneous API requests. |
| [ERR\_NGROK\_226](/docs/errors/err_ngrok_226) | Your account is rate limited to `MAX` API requests per `INTERVAL`. |
| [ERR\_NGROK\_227](/docs/errors/err_ngrok_227) | The ID `VAL` is invalid. Expected an ID with a prefix of `PREFIX`. |
| [ERR\_NGROK\_228](/docs/errors/err_ngrok_228) | The ID `VAL` is not a valid Certificate Authority ID. |
| [ERR\_NGROK\_229](/docs/errors/err_ngrok_229) | The ID `VAL` is not a valid IP Policy ID. |
| [ERR\_NGROK\_230](/docs/errors/err_ngrok_230) | The query part of the requested URI is invalid: `ERR`. Check your API client implementation and review the API documentation: [https://ngrok.com/docs/api-reference/](https://ngrok.com/docs/api-reference/). |
| [ERR\_NGROK\_231](/docs/errors/err_ngrok_231) | The query part of the requested URI includes unknown parameters: `UNKNOWN`. The supported parameters are: `SUPPORTED`. Check your API client implementation and review the API documentation: [https://ngrok.com/docs/api-reference/](https://ngrok.com/docs/api-reference/). |
| [ERR\_NGROK\_232](/docs/errors/err_ngrok_232) | The request must specify only a single value for the `NAME` parameter but got `COUNT`: `VALUES`. Check your API client implementation and review the API documentation: [https://ngrok.com/docs/api-reference/](https://ngrok.com/docs/api-reference/). |
| [ERR\_NGROK\_233](/docs/errors/err_ngrok_233) | The page size limit must be between 1 and `MAX` but `VAL` was provided. |
| [ERR\_NGROK\_235](/docs/errors/err_ngrok_235) | The Format `VAL` is missing or is not a valid Event Destination Format. Supported formats are: `SUPPORTED`. |
| [ERR\_NGROK\_236](/docs/errors/err_ngrok_236) | The destination target is invalid. Expected fields include one of the following: `TARGETS` |
| [ERR\_NGROK\_238](/docs/errors/err_ngrok_238) | The provided event type: `TYP` is not valid. Valid event types are `ID` |
| [ERR\_NGROK\_239](/docs/errors/err_ngrok_239) | The provided field: `TYP` is not valid. |
| [ERR\_NGROK\_240](/docs/errors/err_ngrok_240) | The provided event destination auth is invalid. |
| [ERR\_NGROK\_241](/docs/errors/err_ngrok_241) | The value "`TS`" is not a valid RFC3339 timestamp. Error while parsing: "`ERR`". |
| [ERR\_NGROK\_242](/docs/errors/err_ngrok_242) | The ID `VAL` is not a valid Backend ID. |
| [ERR\_NGROK\_243](/docs/errors/err_ngrok_243) | The ID `VAL` is invalid. Expected an ID with prefix one of `PREFIXES`. |
| [ERR\_NGROK\_244](/docs/errors/err_ngrok_244) | The page size limit must be a number between 1 and `MAX` but `VAL` was provided. |
| [ERR\_NGROK\_247](/docs/errors/err_ngrok_247) | The account `ACCOUNT` has been suspended for non-payment. Update your payment method to pay your outstanding bill and resume service: [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) |
| [ERR\_NGROK\_248](/docs/errors/err_ngrok_248) | The endpoint create request passed an invalid type of `TYPE`. Currently we only support creation of cloud endpoints on this route. |
| [ERR\_NGROK\_249](/docs/errors/err_ngrok_249) | The endpoint URL provided is not a valid URL: `URL`. Ensure the URL has a proper scheme, domain, and if a TCP url, port. |
| [ERR\_NGROK\_250](/docs/errors/err_ngrok_250) | Invalid CEL query: `DETAIL` |
| [ERR\_NGROK\_251](/docs/errors/err_ngrok_251) | `DETAIL` |
| [ERR\_NGROK\_252](/docs/errors/err_ngrok_252) | `REASON` |
| [ERR\_NGROK\_253](/docs/errors/err_ngrok_253) | `REASON` |
| [ERR\_NGROK\_254](/docs/errors/err_ngrok_254) | `REASON` |
| [ERR\_NGROK\_255](/docs/errors/err_ngrok_255) | `REASON` |
| [ERR\_NGROK\_256](/docs/errors/err_ngrok_256) | Only the access token's owner or an account admin can change it. |
| [ERR\_NGROK\_300](/docs/errors/err_ngrok_300) | The authtoken credential `ID` has been revoked |
| [ERR\_NGROK\_301](/docs/errors/err_ngrok_301) | The bind payload you specified is not valid. |
| [ERR\_NGROK\_307](/docs/errors/err_ngrok_307) | You must reserve an address for your account before it can be used. |
| [ERR\_NGROK\_308](/docs/errors/err_ngrok_308) | The credential ACL policy does not permit binding this address. |
| [ERR\_NGROK\_309](/docs/errors/err_ngrok_309) | This address is reserved for another account. |
| [ERR\_NGROK\_310](/docs/errors/err_ngrok_310) | Only Hobbyist and Pay-as-you-go plans may create endpoints with reserved addresses. |
| [ERR\_NGROK\_311](/docs/errors/err_ngrok_311) | This address is allocated for a different region. |
| [ERR\_NGROK\_312](/docs/errors/err_ngrok_312) | Failed to create a TLS endpoint for the account `ACCOUNT`. |
| [ERR\_NGROK\_313](/docs/errors/err_ngrok_313) | Only paid plans may create endpoints with custom subdomains. |
| [ERR\_NGROK\_314](/docs/errors/err_ngrok_314) | Only paid plans may create endpoints with custom hostnames. |
| [ERR\_NGROK\_315](/docs/errors/err_ngrok_315) | Wildcard domains are a feature reserved for ngrok's Pay-as-you-go plan. |
| [ERR\_NGROK\_316](/docs/errors/err_ngrok_316) | The credential ACL policy does not permit binding this name. |
| [ERR\_NGROK\_317](/docs/errors/err_ngrok_317) | You cannot create an endpoint with the domain `DOMAIN` in region |
| [ERR\_NGROK\_318](/docs/errors/err_ngrok_318) | You must reserve a wildcard domain for your account before you can use it to create endpoints. |
| [ERR\_NGROK\_319](/docs/errors/err_ngrok_319) | You must reserve a custom hostname for your account before it can be used to create endpoints. |
| [ERR\_NGROK\_320](/docs/errors/err_ngrok_320) | This domain is reserved for another account. |
| [ERR\_NGROK\_321](/docs/errors/err_ngrok_321) | Wildcard names must be reserved exactly. |
| [ERR\_NGROK\_322](/docs/errors/err_ngrok_322) | This name is reserved in a different region. |
| [ERR\_NGROK\_324](/docs/errors/err_ngrok_324) | Your account may not run more than `MAX` endpoints over a single ngrok agent session. |
| [ERR\_NGROK\_326](/docs/errors/err_ngrok_326) | Invalid character `CHAR` in domain name. Valid domains may contain only a-z, A-Z, 0-9, . \* and - characters. Failed to create an endpoint with the domain `DOMAIN`. |
| [ERR\_NGROK\_327](/docs/errors/err_ngrok_327) | Domain has an invalid character sequence. Valid domains may not contain repeated periods '..'. Failed to create an endpoint with the domain `DOMAIN`. |
| [ERR\_NGROK\_328](/docs/errors/err_ngrok_328) | Domain part `PART` has an invalid first character. Valid domain parts must begin with a-z, A-Z, 0-9 or \*. Failed to create an endpoint with the domain `DOMAIN`. |
| [ERR\_NGROK\_329](/docs/errors/err_ngrok_329) | Domain part `PART` has an invalid last character. Valid domains must end with a-z A-Z or 0-9. Failed to create an endpoint with the domain `DOMAIN`. |
| [ERR\_NGROK\_330](/docs/errors/err_ngrok_330) | Domain has an invalid character sequence. Valid domains may not contain '--' in positions 3 and 4 unless the domain has a punycode prefix of 'xn--'. Failed to create an endpoint with the domain `DOMAIN`. |
| [ERR\_NGROK\_331](/docs/errors/err_ngrok_331) | You may not create an endpoint using a domain with the TLD `SUFFIX`. This TLD is not reachable over the public internet. Failed to create an endpoint with the domain `DOMAIN`. |
| [ERR\_NGROK\_332](/docs/errors/err_ngrok_332) | `PROTO` is not a supported tunnel protocol |
| [ERR\_NGROK\_333](/docs/errors/err_ngrok_333) | No tunnel found with the ID `ID` |
| [ERR\_NGROK\_334](/docs/errors/err_ngrok_334) | The endpoint `URL` is already online. Either |
| [ERR\_NGROK\_335](/docs/errors/err_ngrok_335) | The bind cookie you specified is malformed. This usually indicates a bug in the client's protocol implementation. |
| [ERR\_NGROK\_336](/docs/errors/err_ngrok_336) | Could not find an account while creating this endpoint. This is either an internal server error or you deleted your account. |
| [ERR\_NGROK\_337](/docs/errors/err_ngrok_337) | The last payment for the `ACCOUNT` account failed. |
| [ERR\_NGROK\_338](/docs/errors/err_ngrok_338) | The account `ACCOUNT` has been suspended. |
| [ERR\_NGROK\_341](/docs/errors/err_ngrok_341) | IP Policy with ID `ID` not found |
| [ERR\_NGROK\_343](/docs/errors/err_ngrok_343) | Endpoint configuration `ID` does not allow the agent to set basic authentication. |
| [ERR\_NGROK\_344](/docs/errors/err_ngrok_344) | Endpoint configuration `ID` does not allow clients to set an IP policy. |
| [ERR\_NGROK\_345](/docs/errors/err_ngrok_345) | Endpoint configuration `ID`s HTTPS module terminates TLS which is incompatible with a 'tls' tunnel. You may either: |
| [ERR\_NGROK\_346](/docs/errors/err_ngrok_346) | Endpoint configuration `ID`s HTTPS module does not terminate TLS which is incompatible with a 'https' tunnel. You may either: |
| [ERR\_NGROK\_347](/docs/errors/err_ngrok_347) | Domain has invalid punycode: `IDNA_ERROR`. Failed to create an endpoint with the domain `DOMAIN`. |
| [ERR\_NGROK\_348](/docs/errors/err_ngrok_348) | Your account is limited to `MAX` sessions. |
| [ERR\_NGROK\_349](/docs/errors/err_ngrok_349) | Your account is rate limited for adding `MAX` sessions per `INTERVAL`. |
| [ERR\_NGROK\_350](/docs/errors/err_ngrok_350) | Your account is limited to `MAX` endpoints in a session. |
| [ERR\_NGROK\_351](/docs/errors/err_ngrok_351) | Your account is rate limited for adding `MAX` endpoints per `INTERVAL`. |
| [ERR\_NGROK\_354](/docs/errors/err_ngrok_354) | Failed to create an endpoint with the domain `DOMAIN`. Nested subdomains of an ngrok base domain `ENDPOINT_DOMAIN` must be reserved first. Alternatively, try `SUGGESTION` instead. |
| [ERR\_NGROK\_355](/docs/errors/err_ngrok_355) | Invalid '\_' in domain name. Valid domains may not contain underscores. Failed to create an endpoint with the domain `DOMAIN`. |
| [ERR\_NGROK\_356](/docs/errors/err_ngrok_356) | The credential ACL policy does not permit binding random TCP addresses. |
| [ERR\_NGROK\_358](/docs/errors/err_ngrok_358) | Your account doesn't have permission to create labeled endpoints. |
| [ERR\_NGROK\_359](/docs/errors/err_ngrok_359) | Invalid basic auth credential. Username must not be zero length. |
| [ERR\_NGROK\_360](/docs/errors/err_ngrok_360) | Invalid basic auth credential. Password must be between `MINLENGTH` and `MAXLENGTH` characters, got `GOTLENGTH`. |
| [ERR\_NGROK\_361](/docs/errors/err_ngrok_361) | Invalid circuit breaker configuration, error threshold percentage must be between 0.0 and 1.0 inclusive, was `VAL`. |
| [ERR\_NGROK\_362](/docs/errors/err_ngrok_362) | Invalid IP restriction configuration, invalid CIDR: `CIDR` |
| [ERR\_NGROK\_363](/docs/errors/err_ngrok_363) | You must specify a supported provider name. Supported providers: \[`SUPPORTED`] |
| [ERR\_NGROK\_364](/docs/errors/err_ngrok_364) | Webhook provider `PROVIDER` is not supported. Supported providers: \[`SUPPORTED`] |
| [ERR\_NGROK\_365](/docs/errors/err_ngrok_365) | OAuth provider `PROVIDER` is not supported. Supported providers: \[`SUPPORTED`] |
| [ERR\_NGROK\_366](/docs/errors/err_ngrok_366) | You may not authorize more than `MAX` emails. Got `GOT`. |
| [ERR\_NGROK\_367](/docs/errors/err_ngrok_367) | You may not authorize more than `MAX` email domains. Got `GOT`. |
| [ERR\_NGROK\_368](/docs/errors/err_ngrok_368) | You may not request more than `MAX` oauth scopes. Got `GOT`. |
| [ERR\_NGROK\_370](/docs/errors/err_ngrok_370) | Added request header should be in key:value format, got `VAL` |
| [ERR\_NGROK\_371](/docs/errors/err_ngrok_371) | Added response header should be in key:value format, got `VAL` |
| [ERR\_NGROK\_372](/docs/errors/err_ngrok_372) | `KEY` is not a valid HTTP header name because it contains at least one invalid character. |
| [ERR\_NGROK\_373](/docs/errors/err_ngrok_373) | `KEY` is not a valid HTTP header name because it contains at least one invalid character. |
| [ERR\_NGROK\_374](/docs/errors/err_ngrok_374) | `VAL` is not a valid HTTP header value: `REASON`. |
| [ERR\_NGROK\_375](/docs/errors/err_ngrok_375) | Duplicate 'add' header, `HEADER` was provided twice with different casings: `CASE_ONE` and `CASE_TWO`. |
| [ERR\_NGROK\_376](/docs/errors/err_ngrok_376) | Exceeded the maximum number of added headers. You specified `VAL`, the maximum is `MAX`. |
| [ERR\_NGROK\_377](/docs/errors/err_ngrok_377) | The header beginning with `PREFIX`...' exceeds the maximum header name length of `BYTES` bytes. |
| [ERR\_NGROK\_378](/docs/errors/err_ngrok_378) | The header value for `HEADERKEY` beginning with `PREFIX`...' exceeds the maximum header value length of `BYTES` bytes. |
| [ERR\_NGROK\_379](/docs/errors/err_ngrok_379) | The sendgrid verification key is not a base64 encoded ecdsa public key. The following error was encountered while trying to parse it: "`ERROR`" |
| [ERR\_NGROK\_380](/docs/errors/err_ngrok_380) | The resource `ID` was referenced, but not found. Retry, and contact support if this error persists. |
| [ERR\_NGROK\_381](/docs/errors/err_ngrok_381) | The host `HOST` and port `PORT` you requested is already reserved by an edge. |
| [ERR\_NGROK\_382](/docs/errors/err_ngrok_382) | The account "`NAME`" may not start an endpoint until the admin's email address is verified. Verify your email at [https://dashboard.ngrok.com/user/settings](https://dashboard.ngrok.com/user/settings) |
| [ERR\_NGROK\_383](/docs/errors/err_ngrok_383) | You may not specify an OAuth Client ID without also specifying a Client Secret. Specify both or neither. |
| [ERR\_NGROK\_384](/docs/errors/err_ngrok_384) | You may not specify an OAuth Client Secret without also specifying a Client ID. Specify both or neither. |
| [ERR\_NGROK\_385](/docs/errors/err_ngrok_385) | You must specify an OIDC Client ID. |
| [ERR\_NGROK\_386](/docs/errors/err_ngrok_386) | You must specify an OIDC Client Secret. |
| [ERR\_NGROK\_387](/docs/errors/err_ngrok_387) | You must specify the OIDC Issuer URL. |
| [ERR\_NGROK\_388](/docs/errors/err_ngrok_388) | You may not request more than `MAX` OIDC scopes. Got `GOT`. |
| [ERR\_NGROK\_389](/docs/errors/err_ngrok_389) | You must specify an OAuth client ID and secret for a custom application or neither client ID nor a secret for the ngrok-managed OAuth application. |
| [ERR\_NGROK\_390](/docs/errors/err_ngrok_390) | You must use your own OAuth application, specifying its client ID and secret, in order to specify scopes. |
| [ERR\_NGROK\_391](/docs/errors/err_ngrok_391) | You may not request an individual OAuth scope with length greater than `MAX`. Got scope `SCOPE` with length `GOT`. |
| [ERR\_NGROK\_392](/docs/errors/err_ngrok_392) | You may not request an individual OIDC scope with length greater than `MAX`. Got scope `SCOPE` with length `GOT`. |
| [ERR\_NGROK\_393](/docs/errors/err_ngrok_393) | When specifying CIDRs to deny, you must specify at least one CIDR to allow. Otherwise all traffic will be denied. Use 0.0.0.0/0 and ::0/0 to accept all traffic not explicitly blocked by your deny rules. |
| [ERR\_NGROK\_394](/docs/errors/err_ngrok_394) | Each tunnel must specify either a protocol or labels, but neither was set. |
| [ERR\_NGROK\_395](/docs/errors/err_ngrok_395) | Bind rules in authtoken ACLs are not supported with labeled endpoints at this time. |
| [ERR\_NGROK\_396](/docs/errors/err_ngrok_396) | Domain `DOMAIN` is not a valid DNS name. No domain part may be more than 63 characters long. |
| [ERR\_NGROK\_397](/docs/errors/err_ngrok_397) | Domain `DOMAIN` is not a valid DNS name. Domains may not be more than 253 characters long. |
| [ERR\_NGROK\_398](/docs/errors/err_ngrok_398) | The `ID` header cannot be removed without specifying a replacement. |
| [ERR\_NGROK\_399](/docs/errors/err_ngrok_399) | The credential ACL policy does not permit binding this label. |
| [ERR\_NGROK\_400](/docs/errors/err_ngrok_400) | The region you specified, `REGION` is invalid. Use one of the following acceptable values: `VALID` |
| [ERR\_NGROK\_401](/docs/errors/err_ngrok_401) | Only accounts on paid plans can reserve domains. |
| [ERR\_NGROK\_402](/docs/errors/err_ngrok_402) | Only the first part of a reserved domain may be a '\*' wildcard. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_403](/docs/errors/err_ngrok_403) | The first subdomain of a wildcard domain must be a single '\*' character. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_404](/docs/errors/err_ngrok_404) | You may not reserve names on ngrok.com. Use an ngrok.io suffix. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_405](/docs/errors/err_ngrok_405) | You may not reserve a domain with the suffix `SUFFIX` in the `WANT` region because names with this suffix must be reserved for the `HAVE` region. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_406](/docs/errors/err_ngrok_406) | Invalid character `CHAR` in domain name. Valid domains may contain only a-z, A-Z, 0-9, . \* and - characters. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_407](/docs/errors/err_ngrok_407) | Domain part `PART` has an invalid first character. Valid domain parts must begin with a-z, A-Z, 0-9 or \*. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_408](/docs/errors/err_ngrok_408) | Domain part `PART` has an invalid last character. Valid domains must end with a-z A-Z or 0-9. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_409](/docs/errors/err_ngrok_409) | Domain has an invalid character sequence. Valid domains may not contain repeated periods '..'. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_410](/docs/errors/err_ngrok_410) | Domain has an invalid character sequence. Valid domains may not contain '--' in positions 3 and 4 unless the domain has a punycode prefix of 'xn--'. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_411](/docs/errors/err_ngrok_411) | You may not reserve a name on the TLD `SUFFIX`. This TLD is not reachable over the public internet. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_412](/docs/errors/err_ngrok_412) | Only accounts on paid plans can reserve endpoints on custom domains. |
| [ERR\_NGROK\_413](/docs/errors/err_ngrok_413) | This domain is already reserved for your account. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_414](/docs/errors/err_ngrok_414) | This domain is already reserved for another account. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_415](/docs/errors/err_ngrok_415) | Your account is limited to `MAX` reserved domains. If you need more domains, upgrade to the Pay-as-you-go plan at: [https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo](https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo). |
| [ERR\_NGROK\_416](/docs/errors/err_ngrok_416) | You may not register a wildcard for all `SUFFIX` domains. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_417](/docs/errors/err_ngrok_417) | This wildcard domain would conflict with a domain reserved for another account. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_418](/docs/errors/err_ngrok_418) | Your account is limited to `MAX` wildcard domains. Email [sales@ngrok.com](mailto:sales@ngrok.com) to purchase additional wildcard domains. |
| [ERR\_NGROK\_419](/docs/errors/err_ngrok_419) | Only Pay-as-you-go accounts can reserve wildcard domains. |
| [ERR\_NGROK\_420](/docs/errors/err_ngrok_420) | A description is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_421](/docs/errors/err_ngrok_421) | Metadata is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_422](/docs/errors/err_ngrok_422) | The reserved domain name update failed because no values were provided. Specify at least one value. |
| [ERR\_NGROK\_423](/docs/errors/err_ngrok_423) | The reserved domain name is limited to `MAX` characters; you are using `VAL` characters. |
| [ERR\_NGROK\_424](/docs/errors/err_ngrok_424) | Domain `DOMAIN` does not require a CNAME record |
| [ERR\_NGROK\_425](/docs/errors/err_ngrok_425) | Domain `DOMAIN` CNAME record not found |
| [ERR\_NGROK\_426](/docs/errors/err_ngrok_426) | Domain `DOMAIN` CNAME record not found, A record `IPS` found |
| [ERR\_NGROK\_427](/docs/errors/err_ngrok_427) | Domain `DOMAIN` CNAME record resolved to `HAVE`, should have been `WANT` |
| [ERR\_NGROK\_428](/docs/errors/err_ngrok_428) | You may not assign endpoint configuration `ID` because it is type `TYPE`. You must assign a configuration with type `EXPECTEDTYPE`. |
| [ERR\_NGROK\_429](/docs/errors/err_ngrok_429) | Domain has invalid punycode: `IDNA_ERROR`. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_430](/docs/errors/err_ngrok_430) | Another account is running an active tunnel on the domain `DOMAIN`. You may not reserve domains that are actively in use. |
| [ERR\_NGROK\_431](/docs/errors/err_ngrok_431) | Your account is limited to `MAX` reserved domains. If you need more domains, you can upgrade to a Pay-as-you-go plan at: [https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo](https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo). |
| [ERR\_NGROK\_432](/docs/errors/err_ngrok_432) | Your account is rate limited for adding `MAX` reserved domains per `INTERVAL`. |
| [ERR\_NGROK\_433](/docs/errors/err_ngrok_433) | Your account is limited to `MAX` reserved wildcard domains. If you need more domains, you can upgrade to a Pay-as-you-go plan at: [https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo](https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo). |
| [ERR\_NGROK\_434](/docs/errors/err_ngrok_434) | Either a certificate or a certificate management policy may be specified, not both |
| [ERR\_NGROK\_435](/docs/errors/err_ngrok_435) | Invalid authority specified in managed certificate policy. |
| [ERR\_NGROK\_436](/docs/errors/err_ngrok_436) | The certificate of a reserved domain with a managed certificate policy can not be detached directly, instead the managed certificate policy itself should be detached. |
| [ERR\_NGROK\_438](/docs/errors/err_ngrok_438) | Invalid '\_' in domain name. Valid domains may not contain underscores. Failed to reserve `DOMAIN`. |
| [ERR\_NGROK\_439](/docs/errors/err_ngrok_439) | The certificate\_management\_policy field must be null for domains owned by ngrok. |
| [ERR\_NGROK\_440](/docs/errors/err_ngrok_440) | Uploaded certificates are not allowed for domains owned by ngrok. |
| [ERR\_NGROK\_441](/docs/errors/err_ngrok_441) | Domain `DOMAIN` does not require an ACME Challenge CNAME record |
| [ERR\_NGROK\_442](/docs/errors/err_ngrok_442) | Domain `RECORD` ACME Challenge CNAME record not found |
| [ERR\_NGROK\_443](/docs/errors/err_ngrok_443) | ACME Challenge `RECORD` CNAME record not found, A record `IPS` found |
| [ERR\_NGROK\_444](/docs/errors/err_ngrok_444) | ACME Challenge `RECORD` CNAME record resolved to `HAVE`, should have been `WANT` |
| [ERR\_NGROK\_445](/docs/errors/err_ngrok_445) | There was an error looking up the DNS `RTYPE` record for domain `DOMAIN` (status: `STATUS`): `MSG` |
| [ERR\_NGROK\_446](/docs/errors/err_ngrok_446) | The domain `DOMAIN` could not be deleted because it is still referenced by an edge or cloud endpoint. |
| [ERR\_NGROK\_447](/docs/errors/err_ngrok_447) | Managed certificates are not allowed on direct subdomains of `DOMAIN`. |
| [ERR\_NGROK\_448](/docs/errors/err_ngrok_448) | The domain `DOMAIN` is not a fully qualified domain name. |
| [ERR\_NGROK\_449](/docs/errors/err_ngrok_449) | You may only specify one of 'name' or 'domain'. |
| [ERR\_NGROK\_450](/docs/errors/err_ngrok_450) | You are not allowed to reserve subdomains of `DOMAIN`. Failed to reserve domain `SUBDOMAIN`. |
| [ERR\_NGROK\_451](/docs/errors/err_ngrok_451) | You are not allowed to change the region of `DOMAIN`. |
| [ERR\_NGROK\_455](/docs/errors/err_ngrok_455) | This subdomain is covered by `WILDCARD_DOMAIN` however the wildcard's CNAME record resolved to `HAVE`, should have been `WANT`. |
| [ERR\_NGROK\_456](/docs/errors/err_ngrok_456) | You are not allowed to specify duplicate regions. Region `DUPLICATE` was specified multiple times. |
| [ERR\_NGROK\_457](/docs/errors/err_ngrok_457) | Custom error template URLs are limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_458](/docs/errors/err_ngrok_458) | You are not allowed to delete your dev domain. |
| [ERR\_NGROK\_459](/docs/errors/err_ngrok_459) | You may not change Region and IP resolution for this domain. |
| [ERR\_NGROK\_460](/docs/errors/err_ngrok_460) | You may not change Region and IP resolution for domains in this account. To access this functionality, upgrade to the Pay-as-you-go plan at: [https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo](https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo) |
| [ERR\_NGROK\_461](/docs/errors/err_ngrok_461) | Your account is limited to `MAX` domain(s) with custom Region and IP resolution. Your account has `COUNT` domain(s) with custom Region and IP resolution. |
| [ERR\_NGROK\_462](/docs/errors/err_ngrok_462) | Region and IP resolution is not available for this domain. The DNS name `NAME` has records that ngrok does not manage. |
| [ERR\_NGROK\_500](/docs/errors/err_ngrok_500) | The region you specified, `REGION` is invalid. Use one of the following acceptable values: `VALID` |
| [ERR\_NGROK\_501](/docs/errors/err_ngrok_501) | Only paid accounts can reserve addresses. |
| [ERR\_NGROK\_502](/docs/errors/err_ngrok_502) | Your account is limited to `MAX` reserved addresses. If you need more addresses, you can upgrade to a Pay-as-you-go plan at: [https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo](https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo). |
| [ERR\_NGROK\_503](/docs/errors/err_ngrok_503) | No available reserved addresses in region `REGION` |
| [ERR\_NGROK\_504](/docs/errors/err_ngrok_504) | A description is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_505](/docs/errors/err_ngrok_505) | Metadata is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_506](/docs/errors/err_ngrok_506) | The reserved address update failed because no values were provided. Specify at least one value. |
| [ERR\_NGROK\_507](/docs/errors/err_ngrok_507) | You may not assign endpoint configuration `ID` because it is type `TYPE`. You must assign a configuration with type 'tcp'. |
| [ERR\_NGROK\_508](/docs/errors/err_ngrok_508) | Your account is limited to `MAX` reserved addresses. If you need more addresses, you can upgrade to a Pay-as-you-go plan at: [https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo](https://dashboard.ngrok.com/billing/choose-a-plan?plan=paygo). |
| [ERR\_NGROK\_509](/docs/errors/err_ngrok_509) | Your account is rate limited for adding `MAX` reserved addresses per `INTERVAL`. |
| [ERR\_NGROK\_511](/docs/errors/err_ngrok_511) | The domain `DOMAIN` has a dangling CNAME record. The CNAME must be deleted before this domain can be reserved. |
| [ERR\_NGROK\_512](/docs/errors/err_ngrok_512) | The domain `DOMAIN` has a dangling A, AAAA, ALIAS or other record pointing to ngrok. The record must be deleted before this domain can be reserved. |
| [ERR\_NGROK\_513](/docs/errors/err_ngrok_513) | The domain `DOMAIN` is not a valid DNS name. No domain part may be more than 63 characters long. |
| [ERR\_NGROK\_514](/docs/errors/err_ngrok_514) | The domain `DOMAIN` is not a valid DNS name. Domains may not be more than 253 characters long. |
| [ERR\_NGROK\_515](/docs/errors/err_ngrok_515) | The domain `DOMAIN` is proxied by Cloudflare. While the record correctly resolves to Cloudflare's edge and may be working correctly, we cannot verify it. If you're experiencing issues with this domain, try disabling the Cloudflare proxy and verify again. |
| [ERR\_NGROK\_516](/docs/errors/err_ngrok_516) | The wildcard `DOMAIN` is proxied by Cloudflare. While the wildcard's covered subdomains resolve to Cloudflare's edge and may be working correctly, we cannot verify the wildcard CNAME. If you're experiencing issues with this wildcard domain, try disabling the Cloudflare proxy on the `DOMAIN` record and verify again. |
| [ERR\_NGROK\_517](/docs/errors/err_ngrok_517) | The ACME Challenge `RECORD` is proxied by Cloudflare. Proxying hides the CNAME needed for validation, so we cannot verify the ACME Challenge even though it may be working correctly. If you're experiencing issues with this domain, try disabling the Cloudflare proxy and verify again. |
| [ERR\_NGROK\_600](/docs/errors/err_ngrok_600) | Invalid ACL rule. An ACL rule must be '\*' or start with 'bind:'. The bind value must match the format of a domain, address, or label. You specified: `RULE`. |
| [ERR\_NGROK\_601](/docs/errors/err_ngrok_601) | This credential is your tunnel token and cannot be deleted, only rotated. |
| [ERR\_NGROK\_602](/docs/errors/err_ngrok_602) | Your account is limited to `MAX` authtokens. Upgrade your account at [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing). |
| [ERR\_NGROK\_603](/docs/errors/err_ngrok_603) | Your account is limited to `MAX` API keys. Upgrade your account at [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing). |
| [ERR\_NGROK\_604](/docs/errors/err_ngrok_604) | A description is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_605](/docs/errors/err_ngrok_605) | Metadata is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_606](/docs/errors/err_ngrok_606) | The credentials update failed because no values were provided. Specify at least one value. |
| [ERR\_NGROK\_607](/docs/errors/err_ngrok_607) | SSH tunnel feature is not enabled on your account. |
| [ERR\_NGROK\_608](/docs/errors/err_ngrok_608) | Your account is limited to `MAX` SSH keys. Upgrade your account at [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing). |
| [ERR\_NGROK\_609](/docs/errors/err_ngrok_609) | The public key `PUBKEY` already exists on your account. |
| [ERR\_NGROK\_610](/docs/errors/err_ngrok_610) | The public key `PUBKEY` is already used in a different account. Remove it from the other ngrok account or generate a new SSH key pair (hint: use ssh-keygen). |
| [ERR\_NGROK\_611](/docs/errors/err_ngrok_611) | Public key is missing or empty. |
| [ERR\_NGROK\_612](/docs/errors/err_ngrok_612) | Invalid public key `PUBKEY`: `ERR` |
| [ERR\_NGROK\_613](/docs/errors/err_ngrok_613) | Your account is limited to `MAX` API keys. |
| [ERR\_NGROK\_614](/docs/errors/err_ngrok_614) | Your account is rate limited for adding `MAX` API keys per `INTERVAL`. |
| [ERR\_NGROK\_615](/docs/errors/err_ngrok_615) | Your account is limited to `MAX` authtokens. |
| [ERR\_NGROK\_617](/docs/errors/err_ngrok_617) | Your account is limited to `MAX` SSH keys. |
| [ERR\_NGROK\_619](/docs/errors/err_ngrok_619) | Your account is not authorized to use this ACL rule type. You specified: `RULE`. |
| [ERR\_NGROK\_620](/docs/errors/err_ngrok_620) | Only Pay-as-you-go plans can use tunnel ACL rules. |
| [ERR\_NGROK\_622](/docs/errors/err_ngrok_622) | Only Pay-as-you-go plans can use SSH ACL rules. |
| [ERR\_NGROK\_627](/docs/errors/err_ngrok_627) | The auth token is already owned by a user and cannot be re-assigned ownership. |
| [ERR\_NGROK\_628](/docs/errors/err_ngrok_628) | The API key is already owned by a user and cannot be re-assigned ownership. |
| [ERR\_NGROK\_629](/docs/errors/err_ngrok_629) | The SSH public key is already owned by a user and cannot be re-assigned ownership. |
| [ERR\_NGROK\_630](/docs/errors/err_ngrok_630) | You must be an admin to set credential ownership. |
| [ERR\_NGROK\_631](/docs/errors/err_ngrok_631) | You may specify only one of owner\_id, owner\_email, or scim\_user\_id. |
| [ERR\_NGROK\_632](/docs/errors/err_ngrok_632) | You may specify either an owner (owner\_id, owner\_email, or scim\_user\_id) or membership\_id, but not both. |
| [ERR\_NGROK\_633](/docs/errors/err_ngrok_633) | Your account is not authorized to specify credential ownership. |
| [ERR\_NGROK\_634](/docs/errors/err_ngrok_634) | No credential owner could be determined. |
| [ERR\_NGROK\_635](/docs/errors/err_ngrok_635) | API access requires that the owner of the API key has write privileges. |
| [ERR\_NGROK\_636](/docs/errors/err_ngrok_636) | The credential owner is marked as inactive on the account. |
| [ERR\_NGROK\_637](/docs/errors/err_ngrok_637) | This credential cannot be deleted because it is the default authtoken tied to `EMAIL`. Removing the user from this account will also delete any associated tokens. |
| [ERR\_NGROK\_638](/docs/errors/err_ngrok_638) | Your account is not allowed to create credentials with pre-computed tokens. To create a new credential, omit pre-computed token field and let ngrok generate one for you. Its value will be available as part of the response. |
| [ERR\_NGROK\_702](/docs/errors/err_ngrok_702) | Too many connections! The tunnel session `SESSION` has violated the rate-limit policy of `THRESHOLD` connections per minute by initiating `COUNT` connections in the last `SECONDS` seconds. Decrease your inbound connection volume or upgrade to a paid plan for additional capacity. |
| [ERR\_NGROK\_703](/docs/errors/err_ngrok_703) | Too many connections! The account hosting this endpoint has violated the rate-limit policy of `THRESHOLD` connections per minute by initiating `COUNT` connections in the last `SECONDS` seconds. Decrease your inbound connection volume or upgrade your account plan for additional capacity. |
| [ERR\_NGROK\_714](/docs/errors/err_ngrok_714) | This ngrok account has reached its simultaneous connections limit. Log into [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) to view your options. |
| [ERR\_NGROK\_715](/docs/errors/err_ngrok_715) | You have exceeded your limit on connections per minute. This limit will reset within 1 minute. If you expect to continually exceed these limits, please upgrade your plan at [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) |
| [ERR\_NGROK\_716](/docs/errors/err_ngrok_716) | This unauthenticated ngrok session has reached its simultaneous connections limit. Sign up for a free account at [https://ngrok.com](https://ngrok.com) for a higher limit. |
| [ERR\_NGROK\_717](/docs/errors/err_ngrok_717) | This unauthenticated ngrok session has reached its connection rate limit. Sign up for a free account at [https://ngrok.com](https://ngrok.com) for a higher limit. |
| [ERR\_NGROK\_718](/docs/errors/err_ngrok_718) | Your account is rate limited to `MAX` bytes incoming traffic per `INTERVAL`. |
| [ERR\_NGROK\_720](/docs/errors/err_ngrok_720) | Your account is rate limited to `MAX` bytes outgoing traffic per `INTERVAL`. |
| [ERR\_NGROK\_722](/docs/errors/err_ngrok_722) | internal server error |
| [ERR\_NGROK\_724](/docs/errors/err_ngrok_724) | No backend is available to serve requests for endpoint `URL`. |
| [ERR\_NGROK\_725](/docs/errors/err_ngrok_725) | This ngrok account has reached its network bandwidth limit for the month. Log into [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) to view your options. |
| [ERR\_NGROK\_727](/docs/errors/err_ngrok_727) | This ngrok account has reached its HTTP requests limit for the month. Log into [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) to view your options. |
| [ERR\_NGROK\_729](/docs/errors/err_ngrok_729) | This ngrok account has reached its TCP connections limit for the month. Log into [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) to view your options. |
| [ERR\_NGROK\_730](/docs/errors/err_ngrok_730) | This ngrok account has reached its TLS connections limit for the month. Log into [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) to view your options. |
| [ERR\_NGROK\_734](/docs/errors/err_ngrok_734) | You have exceeded your limit of `MAX` requests per `INTERVAL`. This limit will reset within 1 minute. If you expect to continually exceed these limits, please upgrade your plan at [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) |
| [ERR\_NGROK\_741](/docs/errors/err_ngrok_741) | Internal server error. |
| [ERR\_NGROK\_742](/docs/errors/err_ngrok_742) | This server is draining connections and cannot accept new ones. Please reconnect to continue. |
| [ERR\_NGROK\_743](/docs/errors/err_ngrok_743) | This server is temporarily shedding traffic due to abnormally high request volume. Please retry shortly. |
| [ERR\_NGROK\_744](/docs/errors/err_ngrok_744) | This ngrok account has reached its TCP connections limit for the minute. It resets within a minute. Log into [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) to view your options. |
| [ERR\_NGROK\_745](/docs/errors/err_ngrok_745) | This ngrok account has reached its TLS connections limit for the minute. It resets within a minute. Log into [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) to view your options. |
| [ERR\_NGROK\_800](/docs/errors/err_ngrok_800) | Unknown stream type: `TYPE`. |
| [ERR\_NGROK\_801](/docs/errors/err_ngrok_801) | The request payload you specified is not valid. |
| [ERR\_NGROK\_802](/docs/errors/err_ngrok_802) | internal server error |
| [ERR\_NGROK\_803](/docs/errors/err_ngrok_803) | The server process is shutting down and refusing new requests. |
| [ERR\_NGROK\_804](/docs/errors/err_ngrok_804) | This ngrok agent does not support remote restarting: `REASON`. |
| [ERR\_NGROK\_805](/docs/errors/err_ngrok_805) | This ngrok agent does not support remote stopping: `REASON`. |
| [ERR\_NGROK\_806](/docs/errors/err_ngrok_806) | This ngrok agent does not support remote updating: `REASON`. |
| [ERR\_NGROK\_807](/docs/errors/err_ngrok_807) | The remote ngrok agent failed to stop because of an error: `ERR` |
| [ERR\_NGROK\_808](/docs/errors/err_ngrok_808) | The remote ngrok agent failed to restart because of an error: `ERR` |
| [ERR\_NGROK\_809](/docs/errors/err_ngrok_809) | The remote ngrok agent failed to update because of an error: `ERR` |
| [ERR\_NGROK\_810](/docs/errors/err_ngrok_810) | There was a networking error while trying to send this operation to the ngrok agent or trying to read the response. This usually indicates that the ngrok agent was in the process of shutting down or reconnecting, but it could also result from a networking timeout or failure. It is possible, but unlikely, that the operation succeeded. |
| [ERR\_NGROK\_811](/docs/errors/err_ngrok_811) | Could not negotiate a protocol version. Requested: "`REQUESTED`", Supported: `SUPPORTED`" |
| [ERR\_NGROK\_812](/docs/errors/err_ngrok_812) | Your request exceeded the maximum size of `SIZE`. |
| [ERR\_NGROK\_813](/docs/errors/err_ngrok_813) | Your message "`MESSAGE`"" is not supported by this version of the protocol: `PROTOVERSION`. |
| [ERR\_NGROK\_814](/docs/errors/err_ngrok_814) | No tunnel with the ID `TUNNELID` is bound to this agent session. |
| [ERR\_NGROK\_1000](/docs/errors/err_ngrok_1000) | Your billing address is too long: `VAL` bytes. Max: `MAX` |
| [ERR\_NGROK\_1001](/docs/errors/err_ngrok_1001) | Your tax ID is too long: `VAL` bytes. Max: `MAX` |
| [ERR\_NGROK\_1002](/docs/errors/err_ngrok_1002) | Your account is limited to `MAX` billing email addresses. Email [support@ngrok.com](mailto:support@ngrok.com) to increase the limit |
| [ERR\_NGROK\_1003](/docs/errors/err_ngrok_1003) | The billing email `ID` (`EMAIL`) may not be deleted |
| [ERR\_NGROK\_1004](/docs/errors/err_ngrok_1004) | The billing email is too long: `VAL` bytes. Max: `MAX` |
| [ERR\_NGROK\_1005](/docs/errors/err_ngrok_1005) | The billing email address `EMAIL` is invalid: `ERR` |
| [ERR\_NGROK\_1006](/docs/errors/err_ngrok_1006) | There was a problem with your credit card: `MSG` |
| [ERR\_NGROK\_1007](/docs/errors/err_ngrok_1007) | Your subscription was updated, but we failed to charge your card: `MSG`. |
| [ERR\_NGROK\_1008](/docs/errors/err_ngrok_1008) | Your account is limited to `MAX` billing email addresses. |
| [ERR\_NGROK\_1010](/docs/errors/err_ngrok_1010) | The email address "`EMAIL`" is invalid. |
| [ERR\_NGROK\_1011](/docs/errors/err_ngrok_1011) | Your account is currently past due. You may only enter a payment method to pay your overdue invoice or switch to the free plan. |
| [ERR\_NGROK\_1012](/docs/errors/err_ngrok_1012) | You may not purchase fewer licenses than users. Your account currently has `USERS` users. |
| [ERR\_NGROK\_1013](/docs/errors/err_ngrok_1013) | Yearly plans can only be downgraded or canceled in their final month. Try again after `TIMESTAMP`. |
| [ERR\_NGROK\_1014](/docs/errors/err_ngrok_1014) | You may only purchase one license product at a time. |
| [ERR\_NGROK\_1015](/docs/errors/err_ngrok_1015) | You are on a legacy custom subscription. Contact [support@ngrok.com](mailto:support@ngrok.com) for help with changing your subscription. |
| [ERR\_NGROK\_1016](/docs/errors/err_ngrok_1016) | Cannot charge customer that has no active payment source. |
| [ERR\_NGROK\_1017](/docs/errors/err_ngrok_1017) | Accounts in bad standing may only switch to a free plan or update their payment method. |
| [ERR\_NGROK\_1018](/docs/errors/err_ngrok_1018) | You may only purchase `COUNT` licenses at the `TIER` tier. |
| [ERR\_NGROK\_1019](/docs/errors/err_ngrok_1019) | The `ADDON` addon is not allowed for this plan. |
| [ERR\_NGROK\_1020](/docs/errors/err_ngrok_1020) | Addon selections for `LICENSE` are not valid. |
| [ERR\_NGROK\_1021](/docs/errors/err_ngrok_1021) | The billing email address `EMAIL` is already added |
| [ERR\_NGROK\_1022](/docs/errors/err_ngrok_1022) | Your invoice tax ID type `INPUT` is not a valid option. |
| [ERR\_NGROK\_1023](/docs/errors/err_ngrok_1023) | Your invoice tax ID country `INPUT` is not a valid option. |
| [ERR\_NGROK\_1024](/docs/errors/err_ngrok_1024) | Your invoice billing address country is too long: `VAL` bytes. Max: `MAX` |
| [ERR\_NGROK\_1025](/docs/errors/err_ngrok_1025) | Your invoice billing address state is too long: `VAL` bytes. Max: `MAX` |
| [ERR\_NGROK\_1026](/docs/errors/err_ngrok_1026) | Your invoice billing address city is too long: `VAL` bytes. Max: `MAX` |
| [ERR\_NGROK\_1027](/docs/errors/err_ngrok_1027) | Your invoice billing address line1 is too long: `VAL` bytes. Max: `MAX` |
| [ERR\_NGROK\_1028](/docs/errors/err_ngrok_1028) | Your invoice billing address line2 is too long: `VAL` bytes. Max: `MAX` |
| [ERR\_NGROK\_1029](/docs/errors/err_ngrok_1029) | Your invoice billing address postal code is too long: `VAL` bytes. Max: `MAX` |
| [ERR\_NGROK\_1030](/docs/errors/err_ngrok_1030) | Your invoice billing address name is too long: `VAL` bytes. Max: `MAX` |
| [ERR\_NGROK\_1031](/docs/errors/err_ngrok_1031) | Tax information is incomplete: Missing Type for Tax ID. Update or remove your tax information before making any changes to your account's subscription. |
| [ERR\_NGROK\_1032](/docs/errors/err_ngrok_1032) | Missing Tax ID for Type. You must supply both the Tax ID and its Type or remove both |
| [ERR\_NGROK\_1033](/docs/errors/err_ngrok_1033) | Our billing provider is temporarily unavailable. Please try again in a few minutes. |
| [ERR\_NGROK\_1034](/docs/errors/err_ngrok_1034) | Your payment for `MSG` has not settled yet. Your account is restored automatically once it clears, so no further action is needed. |
| [ERR\_NGROK\_1035](/docs/errors/err_ngrok_1035) | Another payment attempt for `MSG` is already in progress. Wait a moment and try again. |
| [ERR\_NGROK\_1036](/docs/errors/err_ngrok_1036) | Your subscription ended, so this change didn't apply. Reload the page and try again. |
| [ERR\_NGROK\_1100](/docs/errors/err_ngrok_1100) | No public keys were sent for this SSH tunnel. |
| [ERR\_NGROK\_1101](/docs/errors/err_ngrok_1101) | Too many public keys sent for this SSH tunnel (sent `VAL`, max `MAX`). |
| [ERR\_NGROK\_1102](/docs/errors/err_ngrok_1102) | Could not find your account based on the public keys sent for this SSH tunnel. Anonymous SSH tunneling is not supported. |
| [ERR\_NGROK\_1103](/docs/errors/err_ngrok_1103) | The account `ACCOUNT` doesn't have the SSH tunneling feature enabled. |
| [ERR\_NGROK\_1104](/docs/errors/err_ngrok_1104) | Multiplexing is not supported with SSH tunneling |
| [ERR\_NGROK\_1105](/docs/errors/err_ngrok_1105) | Only one port forward per tunneling session is supported. |
| [ERR\_NGROK\_1106](/docs/errors/err_ngrok_1106) | Could not find `USER` API version. Use `VERSION` as user when connecting with SSH to get the latest version. |
| [ERR\_NGROK\_1107](/docs/errors/err_ngrok_1107) | No tunnel type specified. The SSH command specifies the type of tunnel to create, one of 'http', 'tls', or 'tcp'. |
| [ERR\_NGROK\_1108](/docs/errors/err_ngrok_1108) | `CMD` is not a valid tunnel type. The SSH command must be one of 'http', 'tls', or 'tcp'. |
| [ERR\_NGROK\_1109](/docs/errors/err_ngrok_1109) | `FLAG` flag is not supported when using SSH tunneling |
| [ERR\_NGROK\_1110](/docs/errors/err_ngrok_1110) | Error while parsing the `CMD` command: |
| [ERR\_NGROK\_1111](/docs/errors/err_ngrok_1111) | Timeout while waiting for SSH session |
| [ERR\_NGROK\_1112](/docs/errors/err_ngrok_1112) | Timeout while waiting for port forward request. |
| [ERR\_NGROK\_1113](/docs/errors/err_ngrok_1113) | Cannot use bind port `PORT` when using `CMD` command. |
| [ERR\_NGROK\_1114](/docs/errors/err_ngrok_1114) | Cannot use bind address '-R `HOST`:`PORT`:' with '-remote-addr=`ADDR` parameter. |
| [ERR\_NGROK\_1115](/docs/errors/err_ngrok_1115) | Cannot request a custom TCP port '-R `PORT`:' with '-remote-addr=`ADDR` parameter. |
| [ERR\_NGROK\_1116](/docs/errors/err_ngrok_1116) | Cannot request a custom bind port '-R `PORT`:'. |
| [ERR\_NGROK\_1117](/docs/errors/err_ngrok_1117) | Cannot request a random port with a custom bind address `ADDR` in '-R `ADDR`:0:'. |
| [ERR\_NGROK\_1118](/docs/errors/err_ngrok_1118) | Cannot use binding address '-R `ADDR`:' with '-hostname=`HOSTNAME` parameter. |
| [ERR\_NGROK\_1119](/docs/errors/err_ngrok_1119) | Cannot use binding address '-R `ADDR`:' with '-subdomain=`SUBDOMAIN` parameter. |
| [ERR\_NGROK\_1120](/docs/errors/err_ngrok_1120) | Cannot use '-hostname=`HOSTNAME` with '-subdomain=`SUBDOMAIN` parameter. |
| [ERR\_NGROK\_1121](/docs/errors/err_ngrok_1121) | SSH sessions do not support update. |
| [ERR\_NGROK\_1122](/docs/errors/err_ngrok_1122) | SSH sessions do not support restart. |
| [ERR\_NGROK\_1123](/docs/errors/err_ngrok_1123) | Tunnel '-proxy-proto=`PROXYPROTO` specifies invalid protocol version. |
| [ERR\_NGROK\_1125](/docs/errors/err_ngrok_1125) | HIPAA-enabled accounts cannot use SSH tunneling. |
| [ERR\_NGROK\_1200](/docs/errors/err_ngrok_1200) | Authorized account's primary email `EMAIL` is not verified. |
| [ERR\_NGROK\_1202](/docs/errors/err_ngrok_1202) | You can't enable Google OAuth without first connecting a Google Apps login. |
| [ERR\_NGROK\_1203](/docs/errors/err_ngrok_1203) | You can't enable Google OAuth because your connected Google login does not have a Google Apps domain. |
| [ERR\_NGROK\_1204](/docs/errors/err_ngrok_1204) | You can't delete your payment method while you have an active subscription. |
| [ERR\_NGROK\_1205](/docs/errors/err_ngrok_1205) | You failed to solve the CAPTCHA, please try again. |
| [ERR\_NGROK\_1206](/docs/errors/err_ngrok_1206) | You failed to solve the CAPTCHA, please try again. |
| [ERR\_NGROK\_1207](/docs/errors/err_ngrok_1207) | Cannot switch to an account you are not a member of. |
| [ERR\_NGROK\_1208](/docs/errors/err_ngrok_1208) | You failed to solve the CAPTCHA, please try again. |
| [ERR\_NGROK\_1210](/docs/errors/err_ngrok_1210) | Invalid subscription interval `INTERVAL`. |
| [ERR\_NGROK\_1211](/docs/errors/err_ngrok_1211) | Warning: Your IP does not match the IP Policy for this Account. When IP Restrictions are enforced you will not be able to access the dashboard. Authenticate from an IP in the correct range or update your IP Restrictions. |
| [ERR\_NGROK\_1212](/docs/errors/err_ngrok_1212) | Your IP does not match the IP Policy for this Account. Authenticate from an IP in the correct range or update your IP Restrictions from the ngrok dashboard. [https://dashboard.ngrok.com/ip-restrictions](https://dashboard.ngrok.com/ip-restrictions) |
| [ERR\_NGROK\_1214](/docs/errors/err_ngrok_1214) | Your account is rate limited to `MAX` requests per `INTERVAL`. |
| [ERR\_NGROK\_1215](/docs/errors/err_ngrok_1215) | The user `EMAIL` does not have permissions to invite other team members. |
| [ERR\_NGROK\_1216](/docs/errors/err_ngrok_1216) | The user `EMAIL` does not have permissions to manage team members. |
| [ERR\_NGROK\_1217](/docs/errors/err_ngrok_1217) | The user `EMAIL` does not have permissions to view billing information. |
| [ERR\_NGROK\_1218](/docs/errors/err_ngrok_1218) | The user `EMAIL` does not have permissions to change billing information. |
| [ERR\_NGROK\_1219](/docs/errors/err_ngrok_1219) | The user `EMAIL` does not have permissions to change developer resources. |
| [ERR\_NGROK\_1220](/docs/errors/err_ngrok_1220) | The user `EMAIL` does not have administrative privileges which are required to perform this operation. |
| [ERR\_NGROK\_1221](/docs/errors/err_ngrok_1221) | Refusing to perform an account delete operation because you are using the dashboard with a different active account than the one you requested deletion for. |
| [ERR\_NGROK\_1222](/docs/errors/err_ngrok_1222) | You are not a member of any account. |
| [ERR\_NGROK\_1223](/docs/errors/err_ngrok_1223) | You are logged out, please log back in. |
| [ERR\_NGROK\_1224](/docs/errors/err_ngrok_1224) | You are no longer a member of the current account. |
| [ERR\_NGROK\_1225](/docs/errors/err_ngrok_1225) | You must accept the terms of service and privacy policy to sign up for ngrok. |
| [ERR\_NGROK\_1226](/docs/errors/err_ngrok_1226) | You are disallowed from creating an ngrok account due to violation of the terms of service. |
| [ERR\_NGROK\_1227](/docs/errors/err_ngrok_1227) | The number of login attempts with this email has been exceeded, please try again later. |
| [ERR\_NGROK\_1228](/docs/errors/err_ngrok_1228) | You are no longer an active member of the current account. |
| [ERR\_NGROK\_1229](/docs/errors/err_ngrok_1229) | The resource you are attempting to access requires MFA, please authenticate via a second factor. |
| [ERR\_NGROK\_1230](/docs/errors/err_ngrok_1230) | We do not allow sign ups from your location. Your location was determined using your IP address. |
| [ERR\_NGROK\_1231](/docs/errors/err_ngrok_1231) | The email address `EMAIL` already has an active, unredeemed invitation to this account. |
| [ERR\_NGROK\_1232](/docs/errors/err_ngrok_1232) | We do not allow sign ups from anonymous proxies such as Tor. |
| [ERR\_NGROK\_1233](/docs/errors/err_ngrok_1233) | The email address `EMAIL` is already associated with an SSO Identity Provider connection. Contact support: [support@ngrok.com](mailto:support@ngrok.com) |
| [ERR\_NGROK\_1400](/docs/errors/err_ngrok_1400) | The IP Policy update failed because no values were provided. Specify at least one value |
| [ERR\_NGROK\_1401](/docs/errors/err_ngrok_1401) | The IP Policy Rule update failed because no values were provided. Specify at least one value |
| [ERR\_NGROK\_1402](/docs/errors/err_ngrok_1402) | IP Policy not found |
| [ERR\_NGROK\_1404](/docs/errors/err_ngrok_1404) | IP Policy Rule not found |
| [ERR\_NGROK\_1405](/docs/errors/err_ngrok_1405) | Required parameter is missing. Specify `PARAM` |
| [ERR\_NGROK\_1406](/docs/errors/err_ngrok_1406) | Invalid CIDR: `CIDR` |
| [ERR\_NGROK\_1407](/docs/errors/err_ngrok_1407) | IP Policy with name `NAME` already exists |
| [ERR\_NGROK\_1408](/docs/errors/err_ngrok_1408) | IP Policy Rule with CIDR `CIDR` already exists |
| [ERR\_NGROK\_1409](/docs/errors/err_ngrok_1409) | IP Policy Rule CIDR `CIDR` must be specified using the lowest IP address in the range. Did you mean `SUGGESTION`? |
| [ERR\_NGROK\_1410](/docs/errors/err_ngrok_1410) | Your account is limited to a maximum of `MAX` IP Policies |
| [ERR\_NGROK\_1411](/docs/errors/err_ngrok_1411) | Your account is limited to a maximum of `MAX` IP Policy rules for each IP Policy |
| [ERR\_NGROK\_1412](/docs/errors/err_ngrok_1412) | Your legacy account is not authorized to use per-tunnel IP policies. |
| [ERR\_NGROK\_1413](/docs/errors/err_ngrok_1413) | IP Policy Rule is missing a network mask. Consider using `IP`/`BITS` if you want to target a single host IP. |
| [ERR\_NGROK\_1414](/docs/errors/err_ngrok_1414) | The provided ip\_policy\_id is invalid. Check the value given with your request. |
| [ERR\_NGROK\_1415](/docs/errors/err_ngrok_1415) | Your account is limited to `MAX` IP Policies. |
| [ERR\_NGROK\_1417](/docs/errors/err_ngrok_1417) | Your account is limited to `MAX` rules per IP Policy. |
| [ERR\_NGROK\_1419](/docs/errors/err_ngrok_1419) | Cannot delete only rule (`RULEID`) in use by dashboard IP Restriction (`RESTRICTIONID`). Detach this IP Policy from IP Restriction before deleting this rule. |
| [ERR\_NGROK\_1420](/docs/errors/err_ngrok_1420) | Cannot delete IP Policy (`POLICYID`) because it is referenced by one or more IP Restrictions: (`RESTRICTIONIDS`). Detach this IP Policy from all IP Restrictions before deleting it. |
| [ERR\_NGROK\_1421](/docs/errors/err_ngrok_1421) | The IP Policy Rule description exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_1422](/docs/errors/err_ngrok_1422) | An IP Policy Rule must have an 'action' of either 'allow' or 'deny'. |
| [ERR\_NGROK\_1423](/docs/errors/err_ngrok_1423) | An action should now be specified on the IP Policy Rule, not IP Policy. Contact ngrok support if you need additional time to migrate. |
| [ERR\_NGROK\_1500](/docs/errors/err_ngrok_1500) | Maintenance in progress, operations for some resources are read-only |
| [ERR\_NGROK\_1501](/docs/errors/err_ngrok_1501) | Maintenance in progress, some operations are unavailable |
| [ERR\_NGROK\_1600](/docs/errors/err_ngrok_1600) | Endpoint configuration not found |
| [ERR\_NGROK\_1601](/docs/errors/err_ngrok_1601) | Invalid endpoint configuration ID |
| [ERR\_NGROK\_1602](/docs/errors/err_ngrok_1602) | Invalid endpoint configuration request |
| [ERR\_NGROK\_1607](/docs/errors/err_ngrok_1607) | The IP Policy ID `ID` specified for the IP Policy module does not exist. |
| [ERR\_NGROK\_1608](/docs/errors/err_ngrok_1608) | Endpoint Configurations are deprecated. Use Cloud Endpoints instead. |
| [ERR\_NGROK\_1609](/docs/errors/err_ngrok_1609) | Your account is limited to a maximum of `MAX` endpoint configurations. |
| [ERR\_NGROK\_1611](/docs/errors/err_ngrok_1611) | Invalid endpoint configuration, circuit breaker error threshold percentage must be between 0.0 and 1.0 inclusive, was `VAL`. |
| [ERR\_NGROK\_1612](/docs/errors/err_ngrok_1612) | The auth provider `VAL` does not exist. Specify an auth provider ID or the special value 'agent'. |
| [ERR\_NGROK\_1613](/docs/errors/err_ngrok_1613) | The endpoint configuration exceeds the max number of ip policies. You specified `VAL`, the maximum is `MAX`. |
| [ERR\_NGROK\_1614](/docs/errors/err_ngrok_1614) | The endpoint configuration TLS CA certificate size exceeds the max. You specified `VAL`, the maximum is `MAX`. |
| [ERR\_NGROK\_1615](/docs/errors/err_ngrok_1615) | The endpoint configuration exceeds the max number of headers. You specified `VAL`, the maximum is `MAX`. |
| [ERR\_NGROK\_1616](/docs/errors/err_ngrok_1616) | Invalid endpoint configuration, circuit breaker tripped duration must be greater than 0, was `VAL`. |
| [ERR\_NGROK\_1617](/docs/errors/err_ngrok_1617) | Invalid endpoint configuration, circuit breaker rolling window must be greater than 0, was `VAL`. |
| [ERR\_NGROK\_1618](/docs/errors/err_ngrok_1618) | Invalid endpoint configuration, circuit breaker num buckets must be greater than 0 and less than `MAX`, was `VAL`. |
| [ERR\_NGROK\_1619](/docs/errors/err_ngrok_1619) | The endpoint configuration could not be deleted because it is still referenced by at least one reserved domain or reserved address. |
| [ERR\_NGROK\_1620](/docs/errors/err_ngrok_1620) | The endpoint configuration must specify a type. |
| [ERR\_NGROK\_1621](/docs/errors/err_ngrok_1621) | The module `NAME` is not supported on an endpoint configuration of type `TYPE`. |
| [ERR\_NGROK\_1622](/docs/errors/err_ngrok_1622) | `NAME` is not a valid endpoint configuration type. Must be one of 'http', 'https', 'tcp'. |
| [ERR\_NGROK\_1623](/docs/errors/err_ngrok_1623) | `KEY` is not a valid HTTP header name because it contains at least one invalid character. |
| [ERR\_NGROK\_1624](/docs/errors/err_ngrok_1624) | `VAL` is not a valid HTTP header value: `REASON`. |
| [ERR\_NGROK\_1625](/docs/errors/err_ngrok_1625) | You must specify at least one IP policy in the IP Policy module. |
| [ERR\_NGROK\_1626](/docs/errors/err_ngrok_1626) | SNS webhook validation does not accept a secret. |
| [ERR\_NGROK\_1627](/docs/errors/err_ngrok_1627) | Webhook validation for `T` requires a secret. |
| [ERR\_NGROK\_1628](/docs/errors/err_ngrok_1628) | There were validation errors while saving the endpoint configuration:`ERRS` |
| [ERR\_NGROK\_1629](/docs/errors/err_ngrok_1629) | You must specify a supported provider name. Supported providers: \[`T`] |
| [ERR\_NGROK\_1630](/docs/errors/err_ngrok_1630) | Webhook provider `T` is not supported. Supported providers: \[`TYPE`] |
| [ERR\_NGROK\_1631](/docs/errors/err_ngrok_1631) | Endpoint Configurations are deprecated. Use Cloud Endpoints instead. |
| [ERR\_NGROK\_1632](/docs/errors/err_ngrok_1632) | You may not configure the TLS termination parameter `PARAMETER` when the HTTPS module disables TLS termination. |
| [ERR\_NGROK\_1633](/docs/errors/err_ngrok_1633) | Invalid endpoint configuration, unmanaged provider configurations must specify a client ID and a client secret. |
| [ERR\_NGROK\_1634](/docs/errors/err_ngrok_1634) | Invalid endpoint configuration, custom OAuth scopes on a managed OAuth application are not allowed. Define a custom OAuth application to use custom scopes. |
| [ERR\_NGROK\_1635](/docs/errors/err_ngrok_1635) | Invalid endpoint configuration, OAuth auth check interval must be at least `MIN`, was `ACTUAL`. |
| [ERR\_NGROK\_1636](/docs/errors/err_ngrok_1636) | Invalid endpoint configuration, OAuth may only have one provider configuration but multiple are defined: \[`PROVIDER_NAMES`]. |
| [ERR\_NGROK\_1637](/docs/errors/err_ngrok_1637) | Invalid endpoint configuration, OAuth does not define any provider configurations but one is required. |
| [ERR\_NGROK\_1638](/docs/errors/err_ngrok_1638) | Invalid endpoint configuration, OAuth provider `PROVIDER` requires at least the `SCOPE` scope to authenticate by `AUTH_FEATURE`.' |
| [ERR\_NGROK\_1639](/docs/errors/err_ngrok_1639) | Invalid endpoint configuration, OAuth provider `PROVIDER` contains an invalid email domain: `NAME`. |
| [ERR\_NGROK\_1640](/docs/errors/err_ngrok_1640) | Invalid endpoint configuration, OAuth GitHub Teams must be listed as either numerical ids or in the format 'org\_slug/team\_slug', `TEAM` does not match either format. |
| [ERR\_NGROK\_1641](/docs/errors/err_ngrok_1641) | Endpoint Configurations are deprecated. Use Cloud Endpoints instead. |
| [ERR\_NGROK\_1642](/docs/errors/err_ngrok_1642) | Invalid endpoint configuration, OAuth cookie prefix `PREFIX` must consist of only alphanumeric characters with periods. |
| [ERR\_NGROK\_1643](/docs/errors/err_ngrok_1643) | Invalid endpoint configuration, OAuth provider `PROVIDER` contains an invalid email address, `NAME`. |
| [ERR\_NGROK\_1644](/docs/errors/err_ngrok_1644) | Invalid endpoint configuration, OAuth provider `PROVIDER` contains an email domain with invalid punycode: `NAME`. |
| [ERR\_NGROK\_1645](/docs/errors/err_ngrok_1645) | Invalid endpoint configuration, OAuth provider `PROVIDER` contains an email address with invalid punycode: `NAME`. |
| [ERR\_NGROK\_1646](/docs/errors/err_ngrok_1646) | Invalid endpoint configuration, OAuth provider `PROVIDER` email addresses must be unique, but a duplicate is present: `DUPLICATE`. |
| [ERR\_NGROK\_1647](/docs/errors/err_ngrok_1647) | Invalid endpoint configuration, OAuth provider `PROVIDER` email domains must be unique, but a duplicate is present: `DUPLICATE`. |
| [ERR\_NGROK\_1648](/docs/errors/err_ngrok_1648) | Invalid endpoint configuration, OAuth provider `PROVIDER` teams must be unique, but a duplicate is present: `DUPLICATE`. |
| [ERR\_NGROK\_1649](/docs/errors/err_ngrok_1649) | Invalid endpoint configuration, OAuth provider `PROVIDER` organizations must be unique, but a duplicate is present: `DUPLICATE`. |
| [ERR\_NGROK\_1650](/docs/errors/err_ngrok_1650) | Invalid endpoint configuration, OAuth provider `PROVIDER` groups must be unique, but a duplicate is present: `DUPLICATE`. |
| [ERR\_NGROK\_1651](/docs/errors/err_ngrok_1651) | Invalid endpoint configuration, OAuth provider `PROVIDER` email addresses must not contain empty values |
| [ERR\_NGROK\_1652](/docs/errors/err_ngrok_1652) | Invalid endpoint configuration, OAuth provider `PROVIDER` email domains must not contain empty values |
| [ERR\_NGROK\_1653](/docs/errors/err_ngrok_1653) | Invalid endpoint configuration, OAuth provider `PROVIDER` teams must not contain empty values |
| [ERR\_NGROK\_1654](/docs/errors/err_ngrok_1654) | Invalid endpoint configuration, OAuth provider `PROVIDER` organizations must not contain empty values |
| [ERR\_NGROK\_1655](/docs/errors/err_ngrok_1655) | Invalid endpoint configuration, OAuth provider `PROVIDER` groups must not contain empty values |
| [ERR\_NGROK\_1656](/docs/errors/err_ngrok_1656) | The endpoint configuration exceeds the maximum number of OAuth scopes. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_1657](/docs/errors/err_ngrok_1657) | The endpoint configuration exceeds the maximum number of OAuth Github teams. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_1658](/docs/errors/err_ngrok_1658) | The endpoint configuration exceeds the maximum number of OAuth Github orgs. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_1659](/docs/errors/err_ngrok_1659) | The endpoint configuration exceeds the maximum number of OAuth Google groups. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_1660](/docs/errors/err_ngrok_1660) | The endpoint configuration exceeds the maximum number of OAuth emails. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_1661](/docs/errors/err_ngrok_1661) | The endpoint configuration exceeds the maximum number of OAuth domains. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_1662](/docs/errors/err_ngrok_1662) | The endpoint configuration specifies the following modules which may not be enabled when TLS is not terminated: `MODULE_NAMES`. |
| [ERR\_NGROK\_1667](/docs/errors/err_ngrok_1667) | Invalid endpoint configuration, email addresses must be lowercase but `EMAIL` is not. |
| [ERR\_NGROK\_1668](/docs/errors/err_ngrok_1668) | Invalid endpoint configuration, email domains must be lowercase but `DOMAIN` is not. |
| [ERR\_NGROK\_1669](/docs/errors/err_ngrok_1669) | Duplicate 'add' header, `HEADER` was provided twice with different casings: `CASE_ONE` and `CASE_TWO`. |
| [ERR\_NGROK\_1670](/docs/errors/err_ngrok_1670) | Your account is limited to `MAX` endpoint configurations. |
| [ERR\_NGROK\_1672](/docs/errors/err_ngrok_1672) | The CA ID `ID` specified for the Mutual TLS module does not exist. |
| [ERR\_NGROK\_1673](/docs/errors/err_ngrok_1673) | Description is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_1674](/docs/errors/err_ngrok_1674) | Metadata is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_1675](/docs/errors/err_ngrok_1675) | The Mutual TLS configurations exceeds the limit of `LIMIT` attached certificate authorities. |
| [ERR\_NGROK\_1679](/docs/errors/err_ngrok_1679) | The endpoint configuration specifies conflicting authentication modules. Only one of SAML, OIDC, OAuth or Basic Auth may be enabled. |
| [ERR\_NGROK\_1680](/docs/errors/err_ngrok_1680) | The SAML metadata exceeds the maximum length of `MAX` bytes, got `NBYTES`. |
| [ERR\_NGROK\_1681](/docs/errors/err_ngrok_1681) | You must specify only the SAML IdP metadata or the SAML IdP metadata URL, but not both. |
| [ERR\_NGROK\_1682](/docs/errors/err_ngrok_1682) | Failed to connect to IdP metadata URL `MDURL`: `ERR`. |
| [ERR\_NGROK\_1683](/docs/errors/err_ngrok_1683) | Failed to parse the SAML IdP metadata: `ERR`. |
| [ERR\_NGROK\_1684](/docs/errors/err_ngrok_1684) | Received unexpected status code `STATUSCODE` while fetching metadata URL `MDURL` |
| [ERR\_NGROK\_1685](/docs/errors/err_ngrok_1685) | Failed to parse the SAML IdP metadata fetched from URL `MDURL`: `ERR`. |
| [ERR\_NGROK\_1686](/docs/errors/err_ngrok_1686) | Encountered an error while reading the response body from the IdP metadata URL `MDURL`: `ERR`. |
| [ERR\_NGROK\_1687](/docs/errors/err_ngrok_1687) | The specified OIDC issuer has a maximum length of 255 bytes. The specified value is `N` bytes. |
| [ERR\_NGROK\_1688](/docs/errors/err_ngrok_1688) | The OIDC issuer property is required. |
| [ERR\_NGROK\_1689](/docs/errors/err_ngrok_1689) | The OIDC Client ID property is required. |
| [ERR\_NGROK\_1690](/docs/errors/err_ngrok_1690) | The OIDC Client Secret property is required. |
| [ERR\_NGROK\_1691](/docs/errors/err_ngrok_1691) | One of the SAML IdP Metadata or IdP Metadata URL properties must be specified. |
| [ERR\_NGROK\_1692](/docs/errors/err_ngrok_1692) | Invalid endpoint configuration, session inactivity timeout cannot be more than one year, was `ACTUAL`. |
| [ERR\_NGROK\_1693](/docs/errors/err_ngrok_1693) | "`FORMAT`" is not a supported SAML nameid format. |
| [ERR\_NGROK\_1694](/docs/errors/err_ngrok_1694) | Mutual TLS at edge requires TLS termination at edge. |
| [ERR\_NGROK\_1695](/docs/errors/err_ngrok_1695) | No PEM data found in provided mutual TLS CA. |
| [ERR\_NGROK\_1696](/docs/errors/err_ngrok_1696) | Certificate provided for mutual TLS is not a valid CA. |
| [ERR\_NGROK\_1697](/docs/errors/err_ngrok_1697) | The header beginning with `PREFIX`...' exceeds the maximum header name length of `BYTES` bytes. |
| [ERR\_NGROK\_1698](/docs/errors/err_ngrok_1698) | The header value for `HEADERKEY` beginning with `PREFIX`...' exceeds the maximum header value length of `BYTES` bytes. |
| [ERR\_NGROK\_1699](/docs/errors/err_ngrok_1699) | The sendgrid verification key is not a base64 encoded ecdsa public key. The following error was encountered while trying to parse it: "`ERROR`" |
| [ERR\_NGROK\_1700](/docs/errors/err_ngrok_1700) | Your legacy account is not authorized to use session operations. |
| [ERR\_NGROK\_1701](/docs/errors/err_ngrok_1701) | Your legacy account is not authorized to stop or restart the agent. |
| [ERR\_NGROK\_1702](/docs/errors/err_ngrok_1702) | Your legacy account is not authorized to update the agent. |
| [ERR\_NGROK\_1800](/docs/errors/err_ngrok_1800) | You have reached the maximum of `MAX` IP Policies on a restriction. |
| [ERR\_NGROK\_1801](/docs/errors/err_ngrok_1801) | Invalid IP Restriction. The policy `POLICY_ID` does not exist on your account. |
| [ERR\_NGROK\_1802](/docs/errors/err_ngrok_1802) | Only one IP Restriction is allowed per type. Consider either deleting the existing `TYPE` restriction first, or updating it instead. |
| [ERR\_NGROK\_1803](/docs/errors/err_ngrok_1803) | The provided IP Restriction type "`TYPE`" is invalid. Valid types: `SUPPORTED`. |
| [ERR\_NGROK\_1804](/docs/errors/err_ngrok_1804) | An IP Restriction must specify at least one IP Policy. |
| [ERR\_NGROK\_1805](/docs/errors/err_ngrok_1805) | Only Pay-as-you-go accounts with the Account Governance add-on can use dashboard IP restrictions. |
| [ERR\_NGROK\_1806](/docs/errors/err_ngrok_1806) | Only Pay-as-you-go accounts with the Account Governance add-on can use API IP restrictions. |
| [ERR\_NGROK\_1807](/docs/errors/err_ngrok_1807) | Only Pay-as-you-go accounts with the Account Governance add-on can use agent IP restrictions. |
| [ERR\_NGROK\_1808](/docs/errors/err_ngrok_1808) | Only Pay-as-you-go accounts with the Account Governance add-on can use endpoints IP restrictions. |
| [ERR\_NGROK\_1900](/docs/errors/err_ngrok_1900) | The provided certificate is in an unknown or unsupported format. The error encountered while parsing was: "`ERROR`" |
| [ERR\_NGROK\_1901](/docs/errors/err_ngrok_1901) | No PEM-encoded private key was found in the creation request. |
| [ERR\_NGROK\_1902](/docs/errors/err_ngrok_1902) | The provided private key is encrypted. |
| [ERR\_NGROK\_1903](/docs/errors/err_ngrok_1903) | The provided private key is in an unknown or unsupported format. |
| [ERR\_NGROK\_1904](/docs/errors/err_ngrok_1904) | Your account can't upload custom TLS certificates. |
| [ERR\_NGROK\_1905](/docs/errors/err_ngrok_1905) | Your account can't use managed TLS certificates. |
| [ERR\_NGROK\_1906](/docs/errors/err_ngrok_1906) | The domain `DOMAIN` is not a valid domain name. |
| [ERR\_NGROK\_1907](/docs/errors/err_ngrok_1907) | The ip `IP` is not a valid IP address. |
| [ERR\_NGROK\_1908](/docs/errors/err_ngrok_1908) | Invalid authority `AUTHORITY`. Valid authorities: `SUPPORTED`. |
| [ERR\_NGROK\_1909](/docs/errors/err_ngrok_1909) | Invalid private key type `TYPE`. Valid types: `SUPPORTED`. |
| [ERR\_NGROK\_1910](/docs/errors/err_ngrok_1910) | The provided PEM data contains a non-zero number of headers, which are not allowed. |
| [ERR\_NGROK\_1911](/docs/errors/err_ngrok_1911) | The provided data is a valid PEM, but it has an unexpected type: `TYPE`. It must be "CERTIFICATE". |
| [ERR\_NGROK\_1912](/docs/errors/err_ngrok_1912) | The upload contained `COUNT` certificates: `CNS`. Only a single certificate may be uploaded at a time. |
| [ERR\_NGROK\_1913](/docs/errors/err_ngrok_1913) | The uploaded certificate's x509 Basic Constraints did not mark it as a certificate authority (see RFC 5280, 4.2.1.9). |
| [ERR\_NGROK\_1914](/docs/errors/err_ngrok_1914) | The description is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_1915](/docs/errors/err_ngrok_1915) | Metadata is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_1916](/docs/errors/err_ngrok_1916) | The description is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_1917](/docs/errors/err_ngrok_1917) | Metadata is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_1918](/docs/errors/err_ngrok_1918) | Your account is not allowed to upload certificate authorities. |
| [ERR\_NGROK\_1919](/docs/errors/err_ngrok_1919) | No certificate PEM data was sent. |
| [ERR\_NGROK\_1920](/docs/errors/err_ngrok_1920) | The certificate data could not be parsed as PEM. Certificate data: "`PREFIX`". |
| [ERR\_NGROK\_1921](/docs/errors/err_ngrok_1921) | The uploaded certificate PEM data exceeds the maximum length limit of `MAX_SIZE` bytes. |
| [ERR\_NGROK\_1922](/docs/errors/err_ngrok_1922) | No PEM-encoded certificate was found in the creation request. |
| [ERR\_NGROK\_1923](/docs/errors/err_ngrok_1923) | The provided certificate and private key do not match each other. |
| [ERR\_NGROK\_1924](/docs/errors/err_ngrok_1924) | The provided private key is actually a certificate. |
| [ERR\_NGROK\_1925](/docs/errors/err_ngrok_1925) | The provided certificate is actually a private key. |
| [ERR\_NGROK\_1926](/docs/errors/err_ngrok_1926) | The uploaded certificate bundle contained the following certificates in this order: \[`ORDER`], however `INVALID` has not been signed by `INTERMEDIATE`. |
| [ERR\_NGROK\_1927](/docs/errors/err_ngrok_1927) | The domain `DOMAIN` is not available for certificate management. |
| [ERR\_NGROK\_1929](/docs/errors/err_ngrok_1929) | Invalid nameserver count. There should be `WANT` but only found `GOT` for `ZONE` |
| [ERR\_NGROK\_1930](/docs/errors/err_ngrok_1930) | Nameservers are not set up correctly for `DOMAIN`, expected `WANT` but got `GOT` |
| [ERR\_NGROK\_1934](/docs/errors/err_ngrok_1934) | Got error `ERROR` where parsing public key `PUBLICKEY` |
| [ERR\_NGROK\_1935](/docs/errors/err_ngrok_1935) | `CERTTYPE` is not a valid SSH certificate type. Valid certificate types: `SUPPORTED`. |
| [ERR\_NGROK\_1936](/docs/errors/err_ngrok_1936) | "`KEYTYPE`" is not a valid SSH key type. Valid key types: `SUPPORTED`. |
| [ERR\_NGROK\_1937](/docs/errors/err_ngrok_1937) | The description is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_1938](/docs/errors/err_ngrok_1938) | Metadata is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_1939](/docs/errors/err_ngrok_1939) | Invalid key size `KEYSIZE`. Valid key sizes: `SUPPORTED`. |
| [ERR\_NGROK\_1940](/docs/errors/err_ngrok_1940) | Key size is supported only with a key type of "rsa", but the specified key type was "`KEYTYPE`". |
| [ERR\_NGROK\_1941](/docs/errors/err_ngrok_1941) | Invalid elliptic curve "`CURVE`". Valid elliptic curves: `SUPPORTED`. |
| [ERR\_NGROK\_1942](/docs/errors/err_ngrok_1942) | Elliptic curve is supported only with a key type of "ecdsa", but the specified key type was "`KEYTYPE`". |
| [ERR\_NGROK\_1943](/docs/errors/err_ngrok_1943) | The SSH CA Certificate duration must be greater than zero; got duration of `DURATION`. |
| [ERR\_NGROK\_1945](/docs/errors/err_ngrok_1945) | The description is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_1946](/docs/errors/err_ngrok_1946) | Metadata is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_1947](/docs/errors/err_ngrok_1947) | The description is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_1948](/docs/errors/err_ngrok_1948) | Metadata is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_1949](/docs/errors/err_ngrok_1949) | The SSH CA `CA` does not exist. |
| [ERR\_NGROK\_1950](/docs/errors/err_ngrok_1950) | Certificates are not supported for public keys of type `KEYTYPE`. |
| [ERR\_NGROK\_1951](/docs/errors/err_ngrok_1951) | The SSH CA `CA` does not exist. |
| [ERR\_NGROK\_1952](/docs/errors/err_ngrok_1952) | The public key to sign in the certificate is required, but no public key was specified. |
| [ERR\_NGROK\_1953](/docs/errors/err_ngrok_1953) | Your account is not allowed to use SSH certificates. |
| [ERR\_NGROK\_1954](/docs/errors/err_ngrok_1954) | Your account is limited to `MAX` Certificate Authorities. |
| [ERR\_NGROK\_1956](/docs/errors/err_ngrok_1956) | Your account is limited to `MAX` SSH Certificate Authorities. |
| [ERR\_NGROK\_1958](/docs/errors/err_ngrok_1958) | Your account is limited to `MAX` SSH Host Certificates. |
| [ERR\_NGROK\_1960](/docs/errors/err_ngrok_1960) | Your account is limited to `MAX` SSH User Certificates. |
| [ERR\_NGROK\_1962](/docs/errors/err_ngrok_1962) | SSH User Certificate duration must be greater than zero; got duration of `DURATION`. |
| [ERR\_NGROK\_1963](/docs/errors/err_ngrok_1963) | SSH Host Certificate duration must be greater than zero; got duration of `DURATION`. |
| [ERR\_NGROK\_1964](/docs/errors/err_ngrok_1964) | Can't delete SSH CA `ID` because an SSH certificate signed by it exists. Delete all host and user SSH certificates signed by this CA before deleting it. |
| [ERR\_NGROK\_1965](/docs/errors/err_ngrok_1965) | The certificate `ID` does not exist. |
| [ERR\_NGROK\_1966](/docs/errors/err_ngrok_1966) | The certificate `ID` could not be deleted because it has an attached Managed Certificate Policy. If this certificate is automatically generated, delete the domain reservation or use a different certificate type. |
| [ERR\_NGROK\_2032](/docs/errors/err_ngrok_2032) | Webhook Validation middleware requires a secret for `PROVIDER`. |
| [ERR\_NGROK\_2062](/docs/errors/err_ngrok_2062) | Paths given in HTTPMux rules must be either empty or absolute. Perhaps you meant to specify '/`PATH`? |
| [ERR\_NGROK\_2063](/docs/errors/err_ngrok_2063) | The method `METHOD` was specified multiple times for the path `PATH`. Each method must be unique among all rules with the same path. |
| [ERR\_NGROK\_2065](/docs/errors/err_ngrok_2065) | HTTPMux must have at least one rule. |
| [ERR\_NGROK\_2067](/docs/errors/err_ngrok_2067) | Too many rules given to HTTPMux. You provided `VAL` rules, but the limit is `MAX`. |
| [ERR\_NGROK\_2069](/docs/errors/err_ngrok_2069) | The method (`METHOD`) specified in an HTTPMux rule is invalid or otherwise not currently supported. |
| [ERR\_NGROK\_2070](/docs/errors/err_ngrok_2070) | The path specified in an HTTPMux rule is too long. The path provided has `VAL` bytes, but the limit is `MAX`. |
| [ERR\_NGROK\_2071](/docs/errors/err_ngrok_2071) | The path specified in an HTTPMux rule is unsupported or otherwise invalid. |
| [ERR\_NGROK\_2087](/docs/errors/err_ngrok_2087) | The sendgrid verification key is not a base64 encoded ecdsa public key. The following error was encountered while trying to parse it: "`ERROR`" |
| [ERR\_NGROK\_2089](/docs/errors/err_ngrok_2089) | Found duplicate routing rule. Each rule must be unique. |
| [ERR\_NGROK\_2090](/docs/errors/err_ngrok_2090) | The user agent filter regular expression `REGEX` is an invalid regular expression: `ERR`. |
| [ERR\_NGROK\_2200](/docs/errors/err_ngrok_2200) | Invalid policy expression. |
| [ERR\_NGROK\_2201](/docs/errors/err_ngrok_2201) | Invalid policy action type `TYP`. |
| [ERR\_NGROK\_2202](/docs/errors/err_ngrok_2202) | Action type `TYP` is not supported for `PHASE` traffic policy rule. |
| [ERR\_NGROK\_2203](/docs/errors/err_ngrok_2203) | Failed to parse the configuration for policy action type `TYP`. |
| [ERR\_NGROK\_2204](/docs/errors/err_ngrok_2204) | Configuration for policy action type `TYP` has invalid value: `FIELD`. |
| [ERR\_NGROK\_2205](/docs/errors/err_ngrok_2205) | Policy action type `TYP` does not support the `PROTO` protocol. |
| [ERR\_NGROK\_2206](/docs/errors/err_ngrok_2206) | A policy must define at least one action. |
| [ERR\_NGROK\_2207](/docs/errors/err_ngrok_2207) | Policy action type `TYP` is unreachable due to a prior terminating action. |
| [ERR\_NGROK\_2208](/docs/errors/err_ngrok_2208) | Failed to parse configuration for `PHASE` `TYPE`: exceeds maximum allowed name length of `MAX`, was `VAL`. |
| [ERR\_NGROK\_2209](/docs/errors/err_ngrok_2209) | Failed to parse configuration for `PHASE` `TYPE`: exceeds maximum allowed value length of `MAX`, was `VAL`. |
| [ERR\_NGROK\_2210](/docs/errors/err_ngrok_2210) | Failed to parse configuration for `PHASE` `TYPE`: name is invalid `NAME`. |
| [ERR\_NGROK\_2211](/docs/errors/err_ngrok_2211) | Failed to parse configuration for `PHASE` `TYPE`: value is invalid `NAME`. |
| [ERR\_NGROK\_2212](/docs/errors/err_ngrok_2212) | Failed to parse configuration for `PHASE` `TYPE`: can have at most `MAX` header values, but `VAL` were provided. |
| [ERR\_NGROK\_2213](/docs/errors/err_ngrok_2213) | Failed to parse configuration for `PHASE` add-headers: contained an invalid template: `TEMPLATE`: `ERR`. |
| [ERR\_NGROK\_2214](/docs/errors/err_ngrok_2214) | Failed to parse configuration for compress: contained an invalid algorithm: `ALGORITHM`. |
| [ERR\_NGROK\_2215](/docs/errors/err_ngrok_2215) | Failed to parse configuration for `ACTION`: `CONFIG` must be between `MIN` and `MAX` inclusive, was `ACTUAL`. |
| [ERR\_NGROK\_2216](/docs/errors/err_ngrok_2216) | Invalid IP Policy Reference(s): `REFERENCE`. |
| [ERR\_NGROK\_2217](/docs/errors/err_ngrok_2217) | Invalid CIDR(s): `CIDR`. |
| [ERR\_NGROK\_2218](/docs/errors/err_ngrok_2218) | Too many entries for `FIELD`. You provided `ENTRIES` entries, but the limit is `LIMIT`. |
| [ERR\_NGROK\_2219](/docs/errors/err_ngrok_2219) | `FIELD` cannot be user-configured. |
| [ERR\_NGROK\_2221](/docs/errors/err_ngrok_2221) | Invalid configuration for `ACTION`: `CONFIG` length of `ACTUAL` exceeded limit of `MAX`. |
| [ERR\_NGROK\_2222](/docs/errors/err_ngrok_2222) | Invalid configuration for `ACTION`: `CONFIG` must be `VALID`, was `ACTUAL`. |
| [ERR\_NGROK\_2223](/docs/errors/err_ngrok_2223) | Invalid configuration for `ACTION`: `CONFIG` cannot be empty. |
| [ERR\_NGROK\_2224](/docs/errors/err_ngrok_2224) | Invalid configuration for action `ACTION`: failed to compile CEL template expressions in `FIELD`. |
| [ERR\_NGROK\_2225](/docs/errors/err_ngrok_2225) | Invalid configuration for `ACTION`: `CONFIG` duration of `ACTUAL` exceeded limit of `MAX`. |
| [ERR\_NGROK\_2226](/docs/errors/err_ngrok_2226) | Invalid configuration for `ACTION`: `CONFIG` must be a URL, but was `ACTUAL`. |
| [ERR\_NGROK\_2227](/docs/errors/err_ngrok_2227) | Invalid configuration for `ACTION`: The issuer URL at `CONFIG` with a value of `ISSUERURL` did not return a valid OpenID Connect Discovery document. |
| [ERR\_NGROK\_2228](/docs/errors/err_ngrok_2228) | Invalid configuration for `ACTION`: Failed to parse `CONFIG`: `REASON`. |
| [ERR\_NGROK\_2229](/docs/errors/err_ngrok_2229) | Failed to validate Traffic Policy for unknown protocol `PROTO`.' |
| [ERR\_NGROK\_2230](/docs/errors/err_ngrok_2230) | Invalid Traffic Policy phase `PHASE` for protocol `PROTO`. |
| [ERR\_NGROK\_2231](/docs/errors/err_ngrok_2231) | Invalid configuration for `ACTION`: `CONFIG` contains duplicate values: `DUPLICATES`. |
| [ERR\_NGROK\_2232](/docs/errors/err_ngrok_2232) | Failed to resolve validated configuration for policy action type `TYP`. |
| [ERR\_NGROK\_2233](/docs/errors/err_ngrok_2233) | Failed to compile resolved configuration for policy action type `TYP`. |
| [ERR\_NGROK\_2234](/docs/errors/err_ngrok_2234) | Invalid configuration for `ACTION`: `CONFIG` is missing required element `ELEMENT`. |
| [ERR\_NGROK\_2235](/docs/errors/err_ngrok_2235) | The traffic policy provided is not guaranteed to handle traffic. Ensure traffic always results in an action, e.g. custom response or forward action. |
| [ERR\_NGROK\_2236](/docs/errors/err_ngrok_2236) | The traffic policy was not able to be parsed: |
| [ERR\_NGROK\_2237](/docs/errors/err_ngrok_2237) | Invalid configuration for `ACTION`: `CONFIG` length of `ACTUAL` does not satisfy minimum length of `MIN`. |
| [ERR\_NGROK\_2238](/docs/errors/err_ngrok_2238) | Failed to resolve interpolated CEL expression. The expression was: `CEL` |
| [ERR\_NGROK\_2239](/docs/errors/err_ngrok_2239) | Invalid policy: Only one auth action allowed per endpoint. |
| [ERR\_NGROK\_2240](/docs/errors/err_ngrok_2240) | Invalid configuration for `ACTION`: `MISSING` is required when `SPECIFIED` is specified |
| [ERR\_NGROK\_2241](/docs/errors/err_ngrok_2241) | Invalid configuration for `ACTION`: The domain `DOMAIN` cannot be used as it doesn't belong to the endpoint. |
| [ERR\_NGROK\_2242](/docs/errors/err_ngrok_2242) | Invalid configuration for `ACTION`: `CONFIG` `DOMAIN` contains invalid puny code. |
| [ERR\_NGROK\_2243](/docs/errors/err_ngrok_2243) | Invalid configuration for `ACTION`: `CONFIG` `DOMAIN` is not a valid domain. |
| [ERR\_NGROK\_2244](/docs/errors/err_ngrok_2244) | Invalid configuration for `PHASE` `ACTION`: `CONFIG` can have at most `MAX` query key/value pairs, but `VAL` were provided. |
| [ERR\_NGROK\_2245](/docs/errors/err_ngrok_2245) | Invalid configuration for `PHASE` `ACTION`: `CONFIG`: exceeds maximum allowed key length of `MAX`, was `VAL`. |
| [ERR\_NGROK\_2246](/docs/errors/err_ngrok_2246) | Invalid configuration for `PHASE` `ACTION`: `CONFIG`: exceeds maximum allowed key length of `MAX`, was `VAL`. |
| [ERR\_NGROK\_2247](/docs/errors/err_ngrok_2247) | Already validated url didn't parse during `STEP` step: `URL` `ERR` |
| [ERR\_NGROK\_2248](/docs/errors/err_ngrok_2248) | HTTPS Edges do not support the on\_tcp\_connect Traffic Policy phase. Use a Cloud Endpoint instead. |
| [ERR\_NGROK\_2249](/docs/errors/err_ngrok_2249) | Memory limit exceeded by `ACTION` action: `ERR` |
| [ERR\_NGROK\_2250](/docs/errors/err_ngrok_2250) | Invalid configuration for `ACTION`: Nested variables are too deep. Maximum nesting allowed is `MAX` |
| [ERR\_NGROK\_2252](/docs/errors/err_ngrok_2252) | Invalid format for set-vars: vars must be a list of maps of exactly size 1 |
| [ERR\_NGROK\_2253](/docs/errors/err_ngrok_2253) | Failed to evaluate CEL expression on `FIELD` for `ACTION` at runtime: `ERR` |
| [ERR\_NGROK\_2254](/docs/errors/err_ngrok_2254) | Failed to resolve CEL expression. The expression was: `CEL` |
| [ERR\_NGROK\_2255](/docs/errors/err_ngrok_2255) | Invalid configuration for `ACTION`: Maximum `ELEMENT` allowed per action is `MAX` |
| [ERR\_NGROK\_2256](/docs/errors/err_ngrok_2256) | The action `ACTION` is not available for your current plan. Upgrade to `PLANS` to use this action. |
| [ERR\_NGROK\_2257](/docs/errors/err_ngrok_2257) | Invalid basic auth credential. Username `USERNAME` fails to meet requirements of RFC 7617 #2.1: `ERR` |
| [ERR\_NGROK\_2258](/docs/errors/err_ngrok_2258) | Invalid basic auth credential. The password of user `USERNAME` fails to meet requirements of RFC 7617 #2.1: `ERR` |
| [ERR\_NGROK\_2259](/docs/errors/err_ngrok_2259) | No endpoints exist in this account |
| [ERR\_NGROK\_2260](/docs/errors/err_ngrok_2260) | No endpoints could be found matching the supplied combination of labels |
| [ERR\_NGROK\_2261](/docs/errors/err_ngrok_2261) | Failed to parse the configuration for policy action type `TYP`. |
| [ERR\_NGROK\_2262](/docs/errors/err_ngrok_2262) | Internal HTTP/HTTPS endpoints do not support the on\_tcp\_connect Traffic Policy phase. Consider using a TCP or TLS endpoint instead. |
| [ERR\_NGROK\_2263](/docs/errors/err_ngrok_2263) | This policy includes paid traffic policy features that are not allowed on your current plan. Upgrade to use this policy. |
| [ERR\_NGROK\_2264](/docs/errors/err_ngrok_2264) | Policy configuration has exceeded its rule per policy limit of `LIMIT`. Please check [https://ngrok.com/features/traffic-policy](https://ngrok.com/features/traffic-policy) to view your options or contact us at [support@ngrok.com](mailto:support@ngrok.com). |
| [ERR\_NGROK\_2265](/docs/errors/err_ngrok_2265) | Policy configuration has exceeded its `TYP` per rule limit of `LIMIT` during `PHASE` at index `IDX`. Please check [https://ngrok.com/features/traffic-policy](https://ngrok.com/features/traffic-policy) to view your options or contact us at [support@ngrok.com](mailto:support@ngrok.com). |
| [ERR\_NGROK\_2266](/docs/errors/err_ngrok_2266) | Traffic policy contains more than one AI Gateway Action. Only one AI Gateway action is allowed per traffic policy. |
| [ERR\_NGROK\_2267](/docs/errors/err_ngrok_2267) | Configuring provider API keys or key selection in Traffic Policy is no longer supported for standard providers. Attach provider keys to your AI Gateway API Key instead: [https://ngrok.com/docs/ai-gateway/guides/migrate-to-attached-provider-keys](https://ngrok.com/docs/ai-gateway/guides/migrate-to-attached-provider-keys). Custom providers can still configure API keys in Traffic Policy. |
| [ERR\_NGROK\_2300](/docs/errors/err_ngrok_2300) | Internal gateway error occurred while processing policy action: `REASON` |
| [ERR\_NGROK\_3002](/docs/errors/err_ngrok_3002) | Error performing TLS handshake: `ERR` |
| [ERR\_NGROK\_3003](/docs/errors/err_ngrok_3003) | This client does not support TLS SNI, but the endpoint's TLS configuration requires SNI. See [https://ngrok.com/docs/cloud-edge/edges/tls#compatible-clients](https://ngrok.com/docs/cloud-edge/edges/tls#compatible-clients) |
| [ERR\_NGROK\_3004](/docs/errors/err_ngrok_3004) | The server returned an invalid or incomplete HTTP response. |
| [ERR\_NGROK\_3005](/docs/errors/err_ngrok_3005) | A connection to the server not be established. |
| [ERR\_NGROK\_3006](/docs/errors/err_ngrok_3006) | The server refused our connection |
| [ERR\_NGROK\_3007](/docs/errors/err_ngrok_3007) | ngrok gateway error |
| [ERR\_NGROK\_3008](/docs/errors/err_ngrok_3008) | None of the configured backends responded in time |
| [ERR\_NGROK\_3009](/docs/errors/err_ngrok_3009) | Received an HTTP network error (status code 0) from a backend |
| [ERR\_NGROK\_3010](/docs/errors/err_ngrok_3010) | Received an HTTP response with unknown status code `CODE` from a backend |
| [ERR\_NGROK\_3100](/docs/errors/err_ngrok_3100) | Your session has expired due to age. |
| [ERR\_NGROK\_3101](/docs/errors/err_ngrok_3101) | We lack permission to retrieve your data from `PROVIDER` and cannot continue. |
| [ERR\_NGROK\_3102](/docs/errors/err_ngrok_3102) | `PROVIDER` requires that you correct an issue with your account prior to using this website. |
| [ERR\_NGROK\_3103](/docs/errors/err_ngrok_3103) | `PROVIDER` requires that you correct an issue with your account prior to using this website: |
| [ERR\_NGROK\_3104](/docs/errors/err_ngrok_3104) | The email "`EMAIL`" associated with your `PROVIDER` account is not valid. |
| [ERR\_NGROK\_3105](/docs/errors/err_ngrok_3105) | You lack the required permission to use this site. |
| [ERR\_NGROK\_3106](/docs/errors/err_ngrok_3106) | The initial information required to authenticate with `PROVIDER` is invalid. |
| [ERR\_NGROK\_3107](/docs/errors/err_ngrok_3107) | The state parameter used to validate your request is missing. |
| [ERR\_NGROK\_3108](/docs/errors/err_ngrok_3108) | The state parameter used to validate your request cannot be read. |
| [ERR\_NGROK\_3109](/docs/errors/err_ngrok_3109) | `PROVIDER` did not provide an email for your account. |
| [ERR\_NGROK\_3110](/docs/errors/err_ngrok_3110) | The email permission from `PROVIDER` was not granted but is required. Ensure that the email permission is granted. |
| [ERR\_NGROK\_3111](/docs/errors/err_ngrok_3111) | All requested permissions with `PROVIDER` must be granted in order to use this site, but the following were not: `PERMISSIONS`. |
| [ERR\_NGROK\_3112](/docs/errors/err_ngrok_3112) | `PROVIDER` has returned an error when attempting to authorize you to use this site: |
| [ERR\_NGROK\_3113](/docs/errors/err_ngrok_3113) | `PROVIDER` denied access to this application when retrieving your information. This is likely caused by expiration or revocation of your authorization. |
| [ERR\_NGROK\_3114](/docs/errors/err_ngrok_3114) | In order to continue, you must authorize this application's access to `PROVIDER`. |
| [ERR\_NGROK\_3115](/docs/errors/err_ngrok_3115) | The redirect\_uri configured for this application is not properly configured or whitelisted with `PROVIDER`. |
| [ERR\_NGROK\_3116](/docs/errors/err_ngrok_3116) | `PROVIDER` denied access to your data when attempting to authorize you. |
| [ERR\_NGROK\_3117](/docs/errors/err_ngrok_3117) | The initial link used to authorize with `PROVIDER` had unsupported parameters. |
| [ERR\_NGROK\_3118](/docs/errors/err_ngrok_3118) | `PROVIDER` denied access to your data. |
| [ERR\_NGROK\_3119](/docs/errors/err_ngrok_3119) | Logging in with `PROVIDER` took more than 15 minutes and was rejected for security. |
| [ERR\_NGROK\_3120](/docs/errors/err_ngrok_3120) | The state parameter required to finish authorization with `PROVIDER` is missing. |
| [ERR\_NGROK\_3121](/docs/errors/err_ngrok_3121) | The nonce cookie required to finish authorization with `PROVIDER` is missing. |
| [ERR\_NGROK\_3122](/docs/errors/err_ngrok_3122) | The access code from `PROVIDER` has expired and cannot be used. |
| [ERR\_NGROK\_3123](/docs/errors/err_ngrok_3123) | The access code from `PROVIDER` has already been used. |
| [ERR\_NGROK\_3124](/docs/errors/err_ngrok_3124) | The state parameter required to finish authorization with `PROVIDER` does not match this host. |
| [ERR\_NGROK\_3125](/docs/errors/err_ngrok_3125) | `PROVIDER` denied access to your data. |
| [ERR\_NGROK\_3126](/docs/errors/err_ngrok_3126) | `PROVIDER` rejected authorization due to a invalid or unknown scope requested by this application. |
| [ERR\_NGROK\_3127](/docs/errors/err_ngrok_3127) | `PROVIDER` rejected authorization due to invalid or expired credentials. |
| [ERR\_NGROK\_3150](/docs/errors/err_ngrok_3150) | An error occurred when retrieving your session. |
| [ERR\_NGROK\_3151](/docs/errors/err_ngrok_3151) | `PROVIDER` rejected use of your session's OAuth token: "`ERROR`". Your session is invalid and cannot continue. |
| [ERR\_NGROK\_3152](/docs/errors/err_ngrok_3152) | An invalid request was sent to `PROVIDER` but its response is required in order to continue. This is a bug and it has been reported; please try again in a couple of hours to see if it has been resolved. |
| [ERR\_NGROK\_3160](/docs/errors/err_ngrok_3160) | An unexpected error occurred when communicating with `PROVIDER`. |
| [ERR\_NGROK\_3161](/docs/errors/err_ngrok_3161) | `PROVIDER` has throttled this application and cannot be reached right now. |
| [ERR\_NGROK\_3162](/docs/errors/err_ngrok_3162) | `PROVIDER` has throttled this application and cannot be reached right now. |
| [ERR\_NGROK\_3163](/docs/errors/err_ngrok_3163) | An error occurred when finishing authorization with `PROVIDER`. This is likely caused by authorization taking too long. |
| [ERR\_NGROK\_3164](/docs/errors/err_ngrok_3164) | An error occurred when authorizing with `PROVIDER`: |
| [ERR\_NGROK\_3165](/docs/errors/err_ngrok_3165) | `PROVIDER` is too busy to handle requests and authorization cannot be completed at this time. |
| [ERR\_NGROK\_3166](/docs/errors/err_ngrok_3166) | `PROVIDER` encountered an error and authorization cannot be completed at this time. |
| [ERR\_NGROK\_3167](/docs/errors/err_ngrok_3167) | `PROVIDER` is too busy to handle requests and required data cannot be retrieved right now. Wait a few minutes before trying again. |
| [ERR\_NGROK\_3200](/docs/errors/err_ngrok_3200) | The endpoint `ENDPOINTURL` is offline. |
| [ERR\_NGROK\_3202](/docs/errors/err_ngrok_3202) | Circuit breaker tripped |
| [ERR\_NGROK\_3203](/docs/errors/err_ngrok_3203) | Request blocked by IP Policy |
| [ERR\_NGROK\_3204](/docs/errors/err_ngrok_3204) | Request failed webhook verification |
| [ERR\_NGROK\_3205](/docs/errors/err_ngrok_3205) | Request blocked by Endpoints IP Restriction |
| [ERR\_NGROK\_3206](/docs/errors/err_ngrok_3206) | Expected a websocket request with a "Connection: upgrade" header but did not receive one. |
| [ERR\_NGROK\_3208](/docs/errors/err_ngrok_3208) | The ngrok account that was hosting this webpage has been banned for violation of ngrok's Terms of Service. |
| [ERR\_NGROK\_3209](/docs/errors/err_ngrok_3209) | Tunnel not found |
| [ERR\_NGROK\_3210](/docs/errors/err_ngrok_3210) | Error forwarding the connection to the ngrok agent |
| [ERR\_NGROK\_3211](/docs/errors/err_ngrok_3211) | The server does not authorize requests from your user-agent |
| [ERR\_NGROK\_3212](/docs/errors/err_ngrok_3212) | Tunnel `HOSTNAME` has multiple bindings but no binding was specified |
| [ERR\_NGROK\_3213](/docs/errors/err_ngrok_3213) | Upgrade request origin forbidden |
| [ERR\_NGROK\_3214](/docs/errors/err_ngrok_3214) | exceeded maximum number of redirects `MAX`: `URLS` |
| [ERR\_NGROK\_3300](/docs/errors/err_ngrok_3300) | URL "state" parameter is invalid |
| [ERR\_NGROK\_3301](/docs/errors/err_ngrok_3301) | URL "state" parameter is expired. |
| [ERR\_NGROK\_3302](/docs/errors/err_ngrok_3302) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_3303](/docs/errors/err_ngrok_3303) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_3304](/docs/errors/err_ngrok_3304) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_3305](/docs/errors/err_ngrok_3305) | This request has expired. Try again. |
| [ERR\_NGROK\_3306](/docs/errors/err_ngrok_3306) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_3307](/docs/errors/err_ngrok_3307) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_3308](/docs/errors/err_ngrok_3308) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_3309](/docs/errors/err_ngrok_3309) | The route match type `TYP` is incompatible with OAuth, OIDC, or SAML. Compatible selector match types are "EXACT\_PATH" or "PATH\_PREFIX". |
| [ERR\_NGROK\_3310](/docs/errors/err_ngrok_3310) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_3311](/docs/errors/err_ngrok_3311) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_3312](/docs/errors/err_ngrok_3312) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_3313](/docs/errors/err_ngrok_3313) | Invalid Auth Cookie Domain: `DOMAIN` |
| [ERR\_NGROK\_3401](/docs/errors/err_ngrok_3401) | Your request lacks valid credentials. |
| [ERR\_NGROK\_3403](/docs/errors/err_ngrok_3403) | You are forbidden from making this request. |
| [ERR\_NGROK\_3406](/docs/errors/err_ngrok_3406) | Token could not be found in request. |
| [ERR\_NGROK\_3408](/docs/errors/err_ngrok_3408) | Configured HTTP Header `TYP` was not found in request. |
| [ERR\_NGROK\_3411](/docs/errors/err_ngrok_3411) | Failed to parse JSON body. |
| [ERR\_NGROK\_3412](/docs/errors/err_ngrok_3412) | Failed to parse form. |
| [ERR\_NGROK\_3413](/docs/errors/err_ngrok_3413) | Configured prefix `TYP` not found. |
| [ERR\_NGROK\_3414](/docs/errors/err_ngrok_3414) | Failed to read content-type header. |
| [ERR\_NGROK\_3415](/docs/errors/err_ngrok_3415) | Tokens in body not supported for HTTP method `TYP`. |
| [ERR\_NGROK\_3416](/docs/errors/err_ngrok_3416) | Token could not be parsed, possibly malformed. |
| [ERR\_NGROK\_3422](/docs/errors/err_ngrok_3422) | Failed to fetch JWKS. |
| [ERR\_NGROK\_3501](/docs/errors/err_ngrok_3501) | ForwardInternal may only forward through `MAX` endpoints. |
| [ERR\_NGROK\_3502](/docs/errors/err_ngrok_3502) | The forward-internal action can't forward between endpoints that use different protocols. This endpoint uses `PARENTPROTO`, and the endpoint you're forwarding to uses `TARGETPROTO`. |
| [ERR\_NGROK\_3601](/docs/errors/err_ngrok_3601) | The response received from the http-request target had a size exceeding the maximum allowed. |
| [ERR\_NGROK\_3602](/docs/errors/err_ngrok_3602) | The configured http-request timeout was reached before a successful request could be made. |
| [ERR\_NGROK\_3603](/docs/errors/err_ngrok_3603) | Request rejected, A loop was detected. |
| [ERR\_NGROK\_3604](/docs/errors/err_ngrok_3604) | HTTP Status Code `CODE` does not allow including a response body. |
| [ERR\_NGROK\_3700](/docs/errors/err_ngrok_3700) | The request was blocked by the WAF. |
| [ERR\_NGROK\_3701](/docs/errors/err_ngrok_3701) | Something went wrong with the WAF. |
| [ERR\_NGROK\_3702](/docs/errors/err_ngrok_3702) | The response was blocked by the WAF. |
| [ERR\_NGROK\_3810](/docs/errors/err_ngrok_3810) | Request timed out after `ACTIONTIMEOUT`. Try a shorter prompt or increase your timeout. See [https://ngrok.com/docs/ai-gateway/reference/error-codes#err\_ngrok\_3810](https://ngrok.com/docs/ai-gateway/reference/error-codes#err_ngrok_3810) for more information. |
| [ERR\_NGROK\_3811](/docs/errors/err_ngrok_3811) | Input too large: `INPUTTOKENS` tokens (max `MAXALLOWED`). Shorten your prompt. See [https://ngrok.com/docs/ai-gateway/reference/error-codes#err\_ngrok\_3811](https://ngrok.com/docs/ai-gateway/reference/error-codes#err_ngrok_3811) for more information. |
| [ERR\_NGROK\_3820](/docs/errors/err_ngrok_3820) | AI Gateway has a new home at [https://app.ngrok.ai](https://app.ngrok.ai). The old ai-gateway traffic policy action has been retired. Existing credits have been migrated to [https://app.ngrok.ai](https://app.ngrok.ai). If you have any questions or issues, please reach out to [support@ngrok.com](mailto:support@ngrok.com). |
| [ERR\_NGROK\_3900](/docs/errors/err_ngrok_3900) | CEL interpolation was unsuccessful in action `ACTIONTYPE` field `FIELD` |
| [ERR\_NGROK\_3901](/docs/errors/err_ngrok_3901) | CEL interpolation in action `ACTIONTYPE` field `FIELD` did not result in a valid regex. |
| [ERR\_NGROK\_3902](/docs/errors/err_ngrok_3902) | Buffering for the body was not successfully initialized for action type `ACTIONTYPE`. |
| [ERR\_NGROK\_3903](/docs/errors/err_ngrok_3903) | The body could not be successfully buffered for action type `ACTIONTYPE` |
| [ERR\_NGROK\_3904](/docs/errors/err_ngrok_3904) | The body content could not be successfully modified for action type `ACTIONTYPE` |
| [ERR\_NGROK\_3905](/docs/errors/err_ngrok_3905) | The content-length header could not be successfully updated for action type `ACTIONTYPE` |
| [ERR\_NGROK\_4001](/docs/errors/err_ngrok_4001) | Plan `PLAN_ID` does not exist. |
| [ERR\_NGROK\_4003](/docs/errors/err_ngrok_4003) | Account name must not be empty. |
| [ERR\_NGROK\_4004](/docs/errors/err_ngrok_4004) | Account name exceeds max length, `LENGTH` bytes, max: `MAX`. |
| [ERR\_NGROK\_4005](/docs/errors/err_ngrok_4005) | Another account is already configured with the GSuite domain `DOMAIN`. |
| [ERR\_NGROK\_4011](/docs/errors/err_ngrok_4011) | Your password must be at least `LENGTH` characters. |
| [ERR\_NGROK\_4012](/docs/errors/err_ngrok_4012) | Your account does not have access to `FEATURE`. |
| [ERR\_NGROK\_4013](/docs/errors/err_ngrok_4013) | You may not create a new account because you are already a member of the free account "`ACCOUNT_NAME`". Upgrade or delete that account first before creating a new account. |
| [ERR\_NGROK\_4014](/docs/errors/err_ngrok_4014) | The account `NAME` was suspended. It may not be deleted. Contact [support@ngrok.com](mailto:support@ngrok.com) if you believe this is an error. |
| [ERR\_NGROK\_4015](/docs/errors/err_ngrok_4015) | The account `NAME` was banned for violation of the terms of service. It may not be deleted. Contact [support@ngrok.com](mailto:support@ngrok.com) if you believe this is an error. |
| [ERR\_NGROK\_4016](/docs/errors/err_ngrok_4016) | You may not create a new account because another account you were the administrator of was suspended. Contact [support@ngrok.com](mailto:support@ngrok.com) if you believe this is an error. |
| [ERR\_NGROK\_4017](/docs/errors/err_ngrok_4017) | You may not create a new account because another account you were the administrator of was banned for violation of the terms of service. Contact [support@ngrok.com](mailto:support@ngrok.com) if you believe this is an error. |
| [ERR\_NGROK\_4018](/docs/errors/err_ngrok_4018) | This ngrok session is not authenticated. ngrok requires an account and a valid credential to start a session. |
| [ERR\_NGROK\_4019](/docs/errors/err_ngrok_4019) | This account cannot be deleted because it has an active billing subscription. Contact [support@ngrok.com](mailto:support@ngrok.com) for help deleting this account. |
| [ERR\_NGROK\_4020](/docs/errors/err_ngrok_4020) | Your password must be less then `LENGTH` characters. |
| [ERR\_NGROK\_4021](/docs/errors/err_ngrok_4021) | This account cannot be deleted because it has an unpaid invoice. Contact [support@ngrok.com](mailto:support@ngrok.com) for help deleting this account. |
| [ERR\_NGROK\_4022](/docs/errors/err_ngrok_4022) | You do not have permission to change the observability capture settings for this account. Contact an admin for this account to change these settings. |
| [ERR\_NGROK\_4023](/docs/errors/err_ngrok_4023) | Your account does not have access to `FEATURE`. |
| [ERR\_NGROK\_4024](/docs/errors/err_ngrok_4024) | Your account plan cannot be downgraded: `REASON` |
| [ERR\_NGROK\_4025](/docs/errors/err_ngrok_4025) | Your account plan cannot be upgraded: `REASON` |
| [ERR\_NGROK\_4026](/docs/errors/err_ngrok_4026) | Your account has run out of credit, please upgrade to continue using paid actions, or use your dev domain and remove all paid traffic policy from it. |
| [ERR\_NGROK\_4027](/docs/errors/err_ngrok_4027) | Your account’s included bandwidth has been depleted. If you still have credit, you may still use it to buy more bandwidth. |
| [ERR\_NGROK\_4028](/docs/errors/err_ngrok_4028) | A reason is required to change MFA enforcement for this account. |
| [ERR\_NGROK\_4029](/docs/errors/err_ngrok_4029) | Just-in-Time provisioning now requires Domain Control. Contact ngrok support at [support@ngrok.com](mailto:support@ngrok.com). |
| [ERR\_NGROK\_4100](/docs/errors/err_ngrok_4100) | The email or password you entered is not valid. |
| [ERR\_NGROK\_4101](/docs/errors/err_ngrok_4101) | A user with the email address `EMAIL` already exists. |
| [ERR\_NGROK\_4103](/docs/errors/err_ngrok_4103) | `EMAIL` is not a valid email address. |
| [ERR\_NGROK\_4104](/docs/errors/err_ngrok_4104) | User name must not be empty. |
| [ERR\_NGROK\_4105](/docs/errors/err_ngrok_4105) | User name exceeds max length, `LENGTH` bytes, max: `MAX`. |
| [ERR\_NGROK\_4106](/docs/errors/err_ngrok_4106) | Your user `EMAIL` was suspended for violation of the terms of service. It may not be deleted. Contact [support@ngrok.com](mailto:support@ngrok.com) if you believe this is an error. |
| [ERR\_NGROK\_4107](/docs/errors/err_ngrok_4107) | Your user `EMAIL` was banned for violation of the terms of service. It may not be deleted. Contact [support@ngrok.com](mailto:support@ngrok.com) if you believe this is an error. |
| [ERR\_NGROK\_4108](/docs/errors/err_ngrok_4108) | Sign ups are disallowed for the email provider "`DOMAIN`". Sign up with a different email provider. |
| [ERR\_NGROK\_4109](/docs/errors/err_ngrok_4109) | Service User name must not be empty. |
| [ERR\_NGROK\_4110](/docs/errors/err_ngrok_4110) | Service User name exceeds max length, `LENGTH` bytes, max: `MAX`. |
| [ERR\_NGROK\_4111](/docs/errors/err_ngrok_4111) | You must be an admin to create, update, or delete Bots. |
| [ERR\_NGROK\_4112](/docs/errors/err_ngrok_4112) | Service User names must be unique within an account. |
| [ERR\_NGROK\_4114](/docs/errors/err_ngrok_4114) | The email domain "`DOMAIN`" does not allow self-serve user registrations. Contact your ngrok administrator or [support@ngrok.com](mailto:support@ngrok.com) for access. |
| [ERR\_NGROK\_4115](/docs/errors/err_ngrok_4115) | The email domain "`DOMAIN`" does not allow account creation. Contact your ngrok administrator or [support@ngrok.com](mailto:support@ngrok.com) for access. |
| [ERR\_NGROK\_4116](/docs/errors/err_ngrok_4116) | The domain of the email entered is registered under a domain control and must signup via SSO |
| [ERR\_NGROK\_4117](/docs/errors/err_ngrok_4117) | The email address `EMAIL` already exists under a similar alias. Use that email address to login. |
| [ERR\_NGROK\_4118](/docs/errors/err_ngrok_4118) | Sign ups are disallowed for the email provided "`EMAIL`". Sign up with a different email address. |
| [ERR\_NGROK\_4119](/docs/errors/err_ngrok_4119) | This account does not have access to service users, please upgrade to a paid plan. |
| [ERR\_NGROK\_4200](/docs/errors/err_ngrok_4200) | You may not delete all or your logins, you must have at least one. |
| [ERR\_NGROK\_4201](/docs/errors/err_ngrok_4201) | This `LOGIN` login is already connected to another ngrok user. |
| [ERR\_NGROK\_4202](/docs/errors/err_ngrok_4202) | A reason is required to convert a user to password login. |
| [ERR\_NGROK\_4203](/docs/errors/err_ngrok_4203) | This user already has an SSO identity bound to a different identity provider. |
| [ERR\_NGROK\_4300](/docs/errors/err_ngrok_4300) | No user with the email address `EMAIL` exists. |
| [ERR\_NGROK\_4301](/docs/errors/err_ngrok_4301) | You have not set a password for this account. Login using Google or GitHub instead. |
| [ERR\_NGROK\_4302](/docs/errors/err_ngrok_4302) | Unable to redeem password: `REASON` |
| [ERR\_NGROK\_4303](/docs/errors/err_ngrok_4303) | A message template is required when bulk expiring passwords. |
| [ERR\_NGROK\_4304](/docs/errors/err_ngrok_4304) | At least one email or user ID must be provided. |
| [ERR\_NGROK\_4305](/docs/errors/err_ngrok_4305) | Message template is not valid: `REASON` |
| [ERR\_NGROK\_4400](/docs/errors/err_ngrok_4400) | An email address is required to invite a new user |
| [ERR\_NGROK\_4401](/docs/errors/err_ngrok_4401) | The invited email address is too long: `LENGTH` bytes. Max `MAX` bytes. |
| [ERR\_NGROK\_4402](/docs/errors/err_ngrok_4402) | The invited user would exceed your current team size limit of `TEAM_SIZE`. Add another seat at: [https://dashboard.ngrok.com/billing/choose-a-plan](https://dashboard.ngrok.com/billing/choose-a-plan). Then you'll be able to invite your team. |
| [ERR\_NGROK\_4403](/docs/errors/err_ngrok_4403) | You cannot invite any more users. Contact [support@ngrok.com](mailto:support@ngrok.com) if you believe this is an error. |
| [ERR\_NGROK\_4404](/docs/errors/err_ngrok_4404) | Unable to redeem invitation: `REASON` |
| [ERR\_NGROK\_4405](/docs/errors/err_ngrok_4405) | `EMAIL` is not a valid email address. |
| [ERR\_NGROK\_4407](/docs/errors/err_ngrok_4407) | You are not currently permitted to enroll in the beta. |
| [ERR\_NGROK\_4408](/docs/errors/err_ngrok_4408) | Feature request suggestions must be between 1 and `MAXLEN` characters, got `LENGTH`. |
| [ERR\_NGROK\_4409](/docs/errors/err_ngrok_4409) | Your account is not allowed to set invitation permissions. |
| [ERR\_NGROK\_4410](/docs/errors/err_ngrok_4410) | You do not have permissions to invite an administrator to the account. Only administrators may invite other administrators. |
| [ERR\_NGROK\_4411](/docs/errors/err_ngrok_4411) | You do not have permissions to invite users to the account. |
| [ERR\_NGROK\_4412](/docs/errors/err_ngrok_4412) | You may not invite users to the account with higher permissions than your own. |
| [ERR\_NGROK\_4413](/docs/errors/err_ngrok_4413) | Developer Read Write must be set on a user if their permissions include Invite. |
| [ERR\_NGROK\_4414](/docs/errors/err_ngrok_4414) | You are not allowed to create invitations, this account uses SCIM 2.0 to manage members. |
| [ERR\_NGROK\_4415](/docs/errors/err_ngrok_4415) | You are not allowed to redeem this invitation, this account uses SCIM 2.0 to manage members. |
| [ERR\_NGROK\_4416](/docs/errors/err_ngrok_4416) | Your email does not match the email intended for this invitation, `EMAIL`. |
| [ERR\_NGROK\_4451](/docs/errors/err_ngrok_4451) | A user with the email address `EMAIL` already exists. |
| [ERR\_NGROK\_4452](/docs/errors/err_ngrok_4452) | The email address being verified, `EMAIL`, belongs to another user. |
| [ERR\_NGROK\_4453](/docs/errors/err_ngrok_4453) | A similar email address to the one being verified, `EMAIL`, belongs to another user. |
| [ERR\_NGROK\_4454](/docs/errors/err_ngrok_4454) | SCIM-managed users cannot change their email. Your email is managed by your identity provider. |
| [ERR\_NGROK\_4455](/docs/errors/err_ngrok_4455) | Users belonging to accounts that enforce SSO cannot change their email. |
| [ERR\_NGROK\_4500](/docs/errors/err_ngrok_4500) | The URL `URL` is not a valid tcp address or URL. Use either hostname:port or a full URL including protocol for HTTP or TLS endpoints. |
| [ERR\_NGROK\_4501](/docs/errors/err_ngrok_4501) | The TCP port `PORT` in `HOST` is not a valid numerical TCP port. |
| [ERR\_NGROK\_4502](/docs/errors/err_ngrok_4502) | The TCP port `PORT` for `HOST` is not within the range of possible ngrok ports. |
| [ERR\_NGROK\_4503](/docs/errors/err_ngrok_4503) | The IP `IP` is not a known ngrok TCP IP. |
| [ERR\_NGROK\_4504](/docs/errors/err_ngrok_4504) | The host `HOST` is not a known ngrok TCP hostname. |
| [ERR\_NGROK\_4701](/docs/errors/err_ngrok_4701) | You must only specify a single SSO configuration but you specified both SAML and OpenID Connect. |
| [ERR\_NGROK\_4702](/docs/errors/err_ngrok_4702) | You cannot delete your last IdP provider when SSO enforced is enabled |
| [ERR\_NGROK\_5000](/docs/errors/err_ngrok_5000) | Your account is limited to `MAX` `RESOURCE`. |
| [ERR\_NGROK\_5001](/docs/errors/err_ngrok_5001) | Your account is rate limited to `MAX` `RESOURCE` per `INTERVAL`. |
| [ERR\_NGROK\_5100](/docs/errors/err_ngrok_5100) | An event destination must specify a destination target. Valid targets include: `TYPE`. |
| [ERR\_NGROK\_5102](/docs/errors/err_ngrok_5102) | You have reached the maximum of `MAX` destinations for your account. |
| [ERR\_NGROK\_5103](/docs/errors/err_ngrok_5103) | No event destinations with ID: `ID` associated with this account. |
| [ERR\_NGROK\_5104](/docs/errors/err_ngrok_5104) | Event Destination role ARN "`ARN`" is not a valid ARN for an aws IAM role. Error: `MSG`. |
| [ERR\_NGROK\_5105](/docs/errors/err_ngrok_5105) | Event Destination role is missing an external ID. |
| [ERR\_NGROK\_5106](/docs/errors/err_ngrok_5106) | Event Destination target is missing the auth field. |
| [ERR\_NGROK\_5107](/docs/errors/err_ngrok_5107) | Event Destination auth is missing a role or credentials to send events to the destination target. |
| [ERR\_NGROK\_5108](/docs/errors/err_ngrok_5108) | Update to target type not allowed. Create a new destination if you would like to send to a new target. |
| [ERR\_NGROK\_5112](/docs/errors/err_ngrok_5112) | Event Destination "`ID`" cannot be deleted because it is still in use by at least one Event Stream |
| [ERR\_NGROK\_5115](/docs/errors/err_ngrok_5115) | An event destination may not specify more than one destination target. |
| [ERR\_NGROK\_5116](/docs/errors/err_ngrok_5116) | An event destination may not specify more than one type of authentication. |
| [ERR\_NGROK\_5117](/docs/errors/err_ngrok_5117) | The property `NAME` is an immutable property and may not be updated. Create a new destination instead. |
| [ERR\_NGROK\_5118](/docs/errors/err_ngrok_5118) | The partition (`VALUE`) of the provided `FIELD` (`ARN`) is invalid. |
| [ERR\_NGROK\_5119](/docs/errors/err_ngrok_5119) | The service (`VALUE`) of the provided `FIELD` (`ARN`) is invalid. |
| [ERR\_NGROK\_5120](/docs/errors/err_ngrok_5120) | The provided `FIELD` (`ARN`) is invalid. Make sure it matches the ARN you obtained from Amazon exactly. |
| [ERR\_NGROK\_5122](/docs/errors/err_ngrok_5122) | `ERR` |
| [ERR\_NGROK\_5123](/docs/errors/err_ngrok_5123) | Event Subscription `ID` not found. |
| [ERR\_NGROK\_5124](/docs/errors/err_ngrok_5124) | Your account can't use the event subscriptions feature. |
| [ERR\_NGROK\_5125](/docs/errors/err_ngrok_5125) | Source `TYP` not found on Event Subscription `ID`. |
| [ERR\_NGROK\_5126](/docs/errors/err_ngrok_5126) | You have reached the maximum of `MAX` destinations on a subscription. |
| [ERR\_NGROK\_5127](/docs/errors/err_ngrok_5127) | The event type for each source must be unique within a subscription. |
| [ERR\_NGROK\_5128](/docs/errors/err_ngrok_5128) | Your account can't create event destinations. |
| [ERR\_NGROK\_5129](/docs/errors/err_ngrok_5129) | The ARN (`ARN`) is not valid for the `SERVICE` service. |
| [ERR\_NGROK\_5130](/docs/errors/err_ngrok_5130) | The ARN (`ARN`) is not valid for the `RESOURCE` resource type. |
| [ERR\_NGROK\_5131](/docs/errors/err_ngrok_5131) | You have reached the maximum of `MAX` event subscriptions for your account. |
| [ERR\_NGROK\_5132](/docs/errors/err_ngrok_5132) | The Datadog API key provided is not authorized to send events into Datadog: `ERR` |
| [ERR\_NGROK\_5133](/docs/errors/err_ngrok_5133) | Event Destination target is missing API Key. |
| [ERR\_NGROK\_5134](/docs/errors/err_ngrok_5134) | The Datadog site provided (`DDSITE`) is not valid, please see the "SITE" column from [https://docs.datadoghq.com/getting\_started/site/#access-the-datadog-site](https://docs.datadoghq.com/getting_started/site/#access-the-datadog-site) |
| [ERR\_NGROK\_5135](/docs/errors/err_ngrok_5135) | Your account can't use the event source filter feature. |
| [ERR\_NGROK\_5136](/docs/errors/err_ngrok_5136) | The provided azure logs ingestion data collection rule ID is missing or invalid. |
| [ERR\_NGROK\_5137](/docs/errors/err_ngrok_5137) | The provided azure logs ingestion data collection stream name is missing or invalid. |
| [ERR\_NGROK\_5138](/docs/errors/err_ngrok_5138) | The provided azure logs ingestion URI is missing or invalid. |
| [ERR\_NGROK\_5139](/docs/errors/err_ngrok_5139) | The provided azure configuration is invalid: \$`ERR` |
| [ERR\_NGROK\_5140](/docs/errors/err_ngrok_5140) | One or more provided fields are invalid: \$`ERR` |
| [ERR\_NGROK\_5141](/docs/errors/err_ngrok_5141) | Your account requires the Account Governance add-on to export audit events. Only http\_request\_completed and tcp\_connection\_closed events can be exported without this add-on. |
| [ERR\_NGROK\_5200](/docs/errors/err_ngrok_5200) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_5201](/docs/errors/err_ngrok_5201) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_5202](/docs/errors/err_ngrok_5202) | Encountered an error while communicating with the OIDC provider: |
| [ERR\_NGROK\_5203](/docs/errors/err_ngrok_5203) | The OIDC provider failed to return a OIDC ID Token. |
| [ERR\_NGROK\_5204](/docs/errors/err_ngrok_5204) | Failed to verify the OIDC ID Token: |
| [ERR\_NGROK\_5205](/docs/errors/err_ngrok_5205) | Failed to extract claims from the OIDC ID Token: |
| [ERR\_NGROK\_5206](/docs/errors/err_ngrok_5206) | The endpoint configuration "`ECID`" does not exist. |
| [ERR\_NGROK\_5207](/docs/errors/err_ngrok_5207) | OIDC is not enabled on the endpoint configuration "`ECID`". |
| [ERR\_NGROK\_5208](/docs/errors/err_ngrok_5208) | Encountered an error while attempting to fetch OIDC provider metadata: |
| [ERR\_NGROK\_5209](/docs/errors/err_ngrok_5209) | The authentication flow was not completed in time. Try authenticating again. |
| [ERR\_NGROK\_5210](/docs/errors/err_ngrok_5210) | The authentication flow was not completed in time. Try authenticating again. |
| [ERR\_NGROK\_5211](/docs/errors/err_ngrok_5211) | The OIDC provider returned the error code "`ERROR`" with the additional details: "`DETAILS`". Try authenticating again. |
| [ERR\_NGROK\_5212](/docs/errors/err_ngrok_5212) | OIDC is not enabled on the domain "`HOSTNAME`". |
| [ERR\_NGROK\_5300](/docs/errors/err_ngrok_5300) | SAML RelayState parameter is invalid. |
| [ERR\_NGROK\_5301](/docs/errors/err_ngrok_5301) | The SAML IdP sent an invalid SAML assertion: |
| [ERR\_NGROK\_5302](/docs/errors/err_ngrok_5302) | The SAML module for the endpoint configuration "`ECID`" disallows IdP-initiated logins. |
| [ERR\_NGROK\_5303](/docs/errors/err_ngrok_5303) | The endpoint configuration "`ECID`" is not attached to any domains. |
| [ERR\_NGROK\_5304](/docs/errors/err_ngrok_5304) | Could not find the domain "`DOMAIN`" specified in the IdP-initiated RelayState. |
| [ERR\_NGROK\_5305](/docs/errors/err_ngrok_5305) | The SAML IdP sent an invalid SAML assertion: |
| [ERR\_NGROK\_5306](/docs/errors/err_ngrok_5306) | SAML RelayState parameter is invalid. |
| [ERR\_NGROK\_5307](/docs/errors/err_ngrok_5307) | The domain "`DOMAIN`" specified in the IdP-initiated RelayState is not attached to the endpoint configuration "`ECID`". |
| [ERR\_NGROK\_5308](/docs/errors/err_ngrok_5308) | The SAML IdP sent an invalid SAML logout response: |
| [ERR\_NGROK\_5309](/docs/errors/err_ngrok_5309) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_5310](/docs/errors/err_ngrok_5310) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_5311](/docs/errors/err_ngrok_5311) | The SAML IdP sent an invalid SAML assertion with `N` Authn statements. |
| [ERR\_NGROK\_5312](/docs/errors/err_ngrok_5312) | You are not a member of the configured authorized groups on the ngrok edge. |
| [ERR\_NGROK\_5313](/docs/errors/err_ngrok_5313) | The authentication flow was not completed in time. Try authenticating again. |
| [ERR\_NGROK\_5314](/docs/errors/err_ngrok_5314) | The logout flow was not completed in time. Try authenticating again. |
| [ERR\_NGROK\_5315](/docs/errors/err_ngrok_5315) | The authentication flow was not completed in time. Try authenticating again. |
| [ERR\_NGROK\_5316](/docs/errors/err_ngrok_5316) | The logout flow was not completed in time. Try authenticating again. |
| [ERR\_NGROK\_5317](/docs/errors/err_ngrok_5317) | The SAML module for the edge route "`RTEID`" disallows IdP-initiated logins. |
| [ERR\_NGROK\_5318](/docs/errors/err_ngrok_5318) | The edge "`EDGID`" is not attached to any domains. |
| [ERR\_NGROK\_5319](/docs/errors/err_ngrok_5319) | Failed to complete IdP-initiated SAML login. The RelayState specified an invalid domain "`DOMAIN`" to redirect to. Ensure that the domain "`DOMAIN`" is configured as a hostport for "`EDGID`". |
| [ERR\_NGROK\_5320](/docs/errors/err_ngrok_5320) | The edge route "`RTEID`" does not exist. |
| [ERR\_NGROK\_5321](/docs/errors/err_ngrok_5321) | The RelayState must be configured with the redirect URL for IdP-initiated logins. |
| [ERR\_NGROK\_5322](/docs/errors/err_ngrok_5322) | The domain "`DOMAIN`" specified in the IdP-initiated RelayState is not attached to the edge "`EDGID`". |
| [ERR\_NGROK\_5323](/docs/errors/err_ngrok_5323) | The SAML module is not enabled for the configuration "`ID`". |
| [ERR\_NGROK\_5324](/docs/errors/err_ngrok_5324) | The ID "`ID`" that was specified is invalid. This usually indicates a malformed URL. |
| [ERR\_NGROK\_5325](/docs/errors/err_ngrok_5325) | Failed to complete IdP-initiated SAML login. Edge does not have any attached domains. Ensure that at least one domain is configured as a hostport for "`EDGID`". |
| [ERR\_NGROK\_5326](/docs/errors/err_ngrok_5326) | Failed to complete IdP-initiated SAML login. The RelayState must be configured with the redirect URL for IdP-initiated logins when using a route selector match type of "`MATCHTYPE`". |
| [ERR\_NGROK\_5327](/docs/errors/err_ngrok_5327) | Failed to parse the SAML configuration for the configuration "`ID`". Please ensure that all URLs in the SAML configuration are well-formed and include a valid scheme, e.g. "https\://". |
| [ERR\_NGROK\_5400](/docs/errors/err_ngrok_5400) | Event Sources for the "`TYP`" event type must specify fields to capture. |
| [ERR\_NGROK\_5401](/docs/errors/err_ngrok_5401) | Event Sources for the "`TYP`" event may not specify fields. |
| [ERR\_NGROK\_5402](/docs/errors/err_ngrok_5402) | Event Sources for the "`TYP`" event may not specify a filter. |
| [ERR\_NGROK\_5403](/docs/errors/err_ngrok_5403) | Event Sources must be configured with fields that match its event type. "`FIELD`" is not a "`TYP`" field |
| [ERR\_NGROK\_5404](/docs/errors/err_ngrok_5404) | Event Source filter is invalid: "`ERR`" |
| [ERR\_NGROK\_5405](/docs/errors/err_ngrok_5405) | Invalid Event Field: "`FIELD`" |
| [ERR\_NGROK\_5406](/docs/errors/err_ngrok_5406) | Field is not yet supported in event filters: "`FIELD`" |
| [ERR\_NGROK\_5500](/docs/errors/err_ngrok_5500) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_5501](/docs/errors/err_ngrok_5501) | The authentication flow was not completed in time. Try authenticating again. |
| [ERR\_NGROK\_5502](/docs/errors/err_ngrok_5502) | Authorization with `PROVIDER` succeeded, but these required scopes not were granted: `SCOPES`. |
| [ERR\_NGROK\_5503](/docs/errors/err_ngrok_5503) | URL "state" parameter is invalid. |
| [ERR\_NGROK\_5504](/docs/errors/err_ngrok_5504) | The authentication flow was not completed in time. Try authenticating again. |
| [ERR\_NGROK\_5507](/docs/errors/err_ngrok_5507) | `ERROR_NAME` `DETAILS` |
| [ERR\_NGROK\_5508](/docs/errors/err_ngrok_5508) | Authorization with `PROVIDER` succeeded, but these required scopes not were granted: `SCOPES`. |
| [ERR\_NGROK\_5510](/docs/errors/err_ngrok_5510) | `PROVIDER` did not provide an email for your account. |
| [ERR\_NGROK\_5511](/docs/errors/err_ngrok_5511) | Email "`EMAIL`" is not authorized for use by this account. |
| [ERR\_NGROK\_5512](/docs/errors/err_ngrok_5512) | Email is malformed. Email "`EMAIL`" is missing an @ sign. |
| [ERR\_NGROK\_5513](/docs/errors/err_ngrok_5513) | Email domain failed to normalize to a FQDN "`DOMAIN`": |
| [ERR\_NGROK\_5517](/docs/errors/err_ngrok_5517) | `PROVIDER` denied access to your data during the final step of authorization: `DESCRIPTION`. |
| [ERR\_NGROK\_5518](/docs/errors/err_ngrok_5518) | `PROVIDER` rejected authorization with access denied: `DESCRIPTION`. |
| [ERR\_NGROK\_5520](/docs/errors/err_ngrok_5520) | `PROVIDER` rejected authorization due to a invalid or unknown scope requested by this application: `DESCRIPTION`. |
| [ERR\_NGROK\_5521](/docs/errors/err_ngrok_5521) | `PROVIDER` rejected authorization due to an internal server error: `DESCRIPTION`. |
| [ERR\_NGROK\_5522](/docs/errors/err_ngrok_5522) | `PROVIDER` is too busy to handle requests and authorization cannot be completed at this time: `DESCRIPTION`. |
| [ERR\_NGROK\_5523](/docs/errors/err_ngrok_5523) | `PROVIDER` rejected authorization as the redirect URL for this application is improperly configured: `DESCRIPTION`. |
| [ERR\_NGROK\_5524](/docs/errors/err_ngrok_5524) | `PROVIDER` rejected authorization: `DESCRIPTION`. |
| [ERR\_NGROK\_5525](/docs/errors/err_ngrok_5525) | `PROVIDER` has throttled this application and cannot be reached right now. |
| [ERR\_NGROK\_5526](/docs/errors/err_ngrok_5526) | `PROVIDER` rejected access to your information. This is likely caused by expiration or revocation of your authorization. |
| [ERR\_NGROK\_5527](/docs/errors/err_ngrok_5527) | `PROVIDER` rejected the final step of authorization due to invalid credentials. |
| [ERR\_NGROK\_5528](/docs/errors/err_ngrok_5528) | The access code from `PROVIDER` has expired and cannot be used. |
| [ERR\_NGROK\_5529](/docs/errors/err_ngrok_5529) | `PROVIDER` denied access to your data during the final step of authorization. |
| [ERR\_NGROK\_5530](/docs/errors/err_ngrok_5530) | OAuth is not enabled on the domain "`HOSTNAME`". |
| [ERR\_NGROK\_5531](/docs/errors/err_ngrok_5531) | `PROVIDER` denied access to your account as the correct account could not be chosen automatically. |
| [ERR\_NGROK\_5532](/docs/errors/err_ngrok_5532) | `PROVIDER` denied access to your account as reauthentication is required. |
| [ERR\_NGROK\_5533](/docs/errors/err_ngrok_5533) | `PROVIDER` had an internal server error when refreshing your information. |
| [ERR\_NGROK\_5534](/docs/errors/err_ngrok_5534) | Encountered an error while attempting to fetch OIDC provider metadata: |
| [ERR\_NGROK\_5535](/docs/errors/err_ngrok_5535) | The OAuth provider "`PROVIDER`" cannot be used without a user-defined client ID and client secret. |
| [ERR\_NGROK\_5536](/docs/errors/err_ngrok_5536) | Encountered an error while fetching user data: `PROVIDER` did not provide a user ID for your account. |
| [ERR\_NGROK\_5537](/docs/errors/err_ngrok_5537) | Encountered an error while resolving CEL expression: |
| [ERR\_NGROK\_5538](/docs/errors/err_ngrok_5538) | Encountered an error while encrypting the field `FIELD`. |
| [ERR\_NGROK\_5539](/docs/errors/err_ngrok_5539) | Encountered an error while decrypting the field `FIELD`. |
| [ERR\_NGROK\_6000](/docs/errors/err_ngrok_6000) | This tunnel was unable to update; this may be temporary, please try again shortly. |
| [ERR\_NGROK\_6001](/docs/errors/err_ngrok_6001) | This tunnel is no longer available as its account was not found. |
| [ERR\_NGROK\_6002](/docs/errors/err_ngrok_6002) | This tunnel is no longer available as its account does not own resources required to run. |
| [ERR\_NGROK\_6003](/docs/errors/err_ngrok_6003) | Endpoint configurations cannot be used with agent-specified basic auth. Either remove the endpoint configuration from this endpoint or restart the agent without basic auth. |
| [ERR\_NGROK\_6006](/docs/errors/err_ngrok_6006) | The Event Destination `EDID` required by `ECID` was not found. If these were recently created or removed, this should be temporary and resolve itself. |
| [ERR\_NGROK\_6008](/docs/errors/err_ngrok_6008) | This endpoint is unavailable as its account is suspended due to lack of payment. |
| [ERR\_NGROK\_6009](/docs/errors/err_ngrok_6009) | The ngrok account that was hosting this webpage has been suspended for violation of ngrok's Terms of Service. |
| [ERR\_NGROK\_6010](/docs/errors/err_ngrok_6010) | Endpoint configuration is incompatible with endpoint; module `MODULE` required by Endpoint Configuration `ECID` is incompatible with `PROTO` endpoints. |
| [ERR\_NGROK\_6011](/docs/errors/err_ngrok_6011) | You may not specify `MIDDLEWARE` options from the ngrok agent because this domain has a configured endpoint configuration: `ECID`. Remove the endpoint configuration from this domain or remove the conflicting options when starting the ngrok agent. |
| [ERR\_NGROK\_6013](/docs/errors/err_ngrok_6013) | Failed to compile filter for Event Subscription `ESID`. |
| [ERR\_NGROK\_6014](/docs/errors/err_ngrok_6014) | Failed to run filter for Event Subscription `ESID`. |
| [ERR\_NGROK\_6018](/docs/errors/err_ngrok_6018) | The Endpoint `HOSTPORT` has both an Endpoint Configuration (`EPCID`) and a Tunnel with incompatible configuration (`TUNNELID`) online. |
| [ERR\_NGROK\_6019](/docs/errors/err_ngrok_6019) | The Endpoint `HOSTPORT` has both an Edge (`EDGID`) and Endpoint Configuration (`EPCID`) configured. |
| [ERR\_NGROK\_6020](/docs/errors/err_ngrok_6020) | The Endpoint `HOSTPORT` has both an Edge (`EDGID`) and Tunnel (`TUNID`) online. |
| [ERR\_NGROK\_6021](/docs/errors/err_ngrok_6021) | HTML content may only be served after you upgrade to a paid account. |
| [ERR\_NGROK\_6022](/docs/errors/err_ngrok_6022) | Before you can serve HTML content, you must sign up for an ngrok account and install your authtoken. |
| [ERR\_NGROK\_6023](/docs/errors/err_ngrok_6023) | HTML content may only be served in this region after you upgrade to a paid account. |
| [ERR\_NGROK\_6024](/docs/errors/err_ngrok_6024) | You are about to visit `HOSTPORT``SERVEDBYSTR`. This website is served for free through ngrok.com. You should only visit this website if you trust whoever sent the link to you. |
| [ERR\_NGROK\_6025](/docs/errors/err_ngrok_6025) | The tunnel `URL` is already bound to another tunnel session. Start the ngrok agent with a different domain. |
| [ERR\_NGROK\_6026](/docs/errors/err_ngrok_6026) | The Endpoint `HOSTPORT` has both a Cloud Endpoint (`CLEPID`) and Tunnel (`TUNID`) online. |
| [ERR\_NGROK\_6027](/docs/errors/err_ngrok_6027) | The Endpoint `HOSTPORT` has both a Cloud Endpoint (`CLEPID`) and Edge (`EDGID`) configured. |
| [ERR\_NGROK\_6028](/docs/errors/err_ngrok_6028) | The Endpoint `HOSTPORT` has both a Cloud Endpoint (`CLEPID`) and Endpoint Configuration (`TUNID`) configured. |
| [ERR\_NGROK\_6029](/docs/errors/err_ngrok_6029) | The traffic policy configured for cloud endpoint `CLEPID` is non-terminating. |
| [ERR\_NGROK\_6030](/docs/errors/err_ngrok_6030) | The url `URL` has multiple endpoints, but they do not all have pooling enabled. |
| [ERR\_NGROK\_6031](/docs/errors/err_ngrok_6031) | HTTP endpoints are disabled for HIPAA-enabled plans |
| [ERR\_NGROK\_6032](/docs/errors/err_ngrok_6032) | This ngrok account is not allowed to use the paid traffic policy features configured on this endpoint. Upgrade your plan to enable this endpoint. |
| [ERR\_NGROK\_6033](/docs/errors/err_ngrok_6033) | Insuffiucient AI Gateway Credits - Your credit balance is too low to use AI Gateway. You can purchase credits from the dashboard: [https://dashboard.ngrok.com/ai-gateways](https://dashboard.ngrok.com/ai-gateways) . If you've already upgraded, the change may take a few minutes to propagate, please try again in a little bit. If you are still experiencing this issue after 20-30 minutes, please contact support. |
| [ERR\_NGROK\_6500](/docs/errors/err_ngrok_6500) | Your account is not authorized to use the backends feature. |
| [ERR\_NGROK\_6501](/docs/errors/err_ngrok_6501) | Cannot save backend reference `ID` because it does not exists. |
| [ERR\_NGROK\_6502](/docs/errors/err_ngrok_6502) | The backend could not be deleted because it is still referenced by at least one backend. |
| [ERR\_NGROK\_6503](/docs/errors/err_ngrok_6503) | Description is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_6504](/docs/errors/err_ngrok_6504) | Metadata is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_6505](/docs/errors/err_ngrok_6505) | Static backend requires address in the host:port form. |
| [ERR\_NGROK\_6506](/docs/errors/err_ngrok_6506) | Static backend address `ADDR` is invalid (`REASON`). Use host:port as address. |
| [ERR\_NGROK\_6507](/docs/errors/err_ngrok_6507) | Static backend address `ADDR` is missing host. Use host:port as address. |
| [ERR\_NGROK\_6508](/docs/errors/err_ngrok_6508) | Tunnel group labels count is limited to `MAX`; you have `VAL` labels. |
| [ERR\_NGROK\_6509](/docs/errors/err_ngrok_6509) | Tunnel group label key length is limited to between `MIN` and `MAX`; key `NAME` has `VAL` characters. |
| [ERR\_NGROK\_6510](/docs/errors/err_ngrok_6510) | Tunnel group label value length is limited to between `MIN` and `MAX`; value `NAME` has `VAL` characters. |
| [ERR\_NGROK\_6511](/docs/errors/err_ngrok_6511) | Weighted backends count is limited to `MAX`; you have `VAL` backends. |
| [ERR\_NGROK\_6512](/docs/errors/err_ngrok_6512) | Weighted backend `ID` weight `VAL` is out of range; it must be between `MIN` and `MAX`. |
| [ERR\_NGROK\_6513](/docs/errors/err_ngrok_6513) | Failover backends may only contain up to `MAX` failover backends; you have `VAL` failover backends. |
| [ERR\_NGROK\_6514](/docs/errors/err_ngrok_6514) | Backend not found. |
| [ERR\_NGROK\_6515](/docs/errors/err_ngrok_6515) | Tunnel Group Backend `ID` did not match any endpoints. |
| [ERR\_NGROK\_6516](/docs/errors/err_ngrok_6516) | HTTP Response Backend `ID` had too large of a body. |
| [ERR\_NGROK\_6517](/docs/errors/err_ngrok_6517) | HTTP Response Backend `ID` had an invalid status code. |
| [ERR\_NGROK\_6522](/docs/errors/err_ngrok_6522) | The header beginning with `PREFIX`...' exceeds the maximum header name length of `BYTES` bytes. |
| [ERR\_NGROK\_6523](/docs/errors/err_ngrok_6523) | The header value for `HEADERKEY` beginning with `PREFIX`...' exceeds the maximum header value length of `BYTES` bytes. |
| [ERR\_NGROK\_6524](/docs/errors/err_ngrok_6524) | A Weighted Backend may not reference the backend `ID` because it is a `BACKENDTYPE` backend. |
| [ERR\_NGROK\_6525](/docs/errors/err_ngrok_6525) | A Failover Backend may not reference the backend `ID` because it is a `BACKENDTYPE` backend. |
| [ERR\_NGROK\_6526](/docs/errors/err_ngrok_6526) | The id `ID` is not a valid backend ID. |
| [ERR\_NGROK\_6527](/docs/errors/err_ngrok_6527) | The id `ID` is invalid; expected an id of type `BACKENDTYPE` backend. |
| [ERR\_NGROK\_6528](/docs/errors/err_ngrok_6528) | Traffic made it to the ngrok edge, but there are no endpoints online serving an app. |
| [ERR\_NGROK\_6529](/docs/errors/err_ngrok_6529) | Your account is not authorized to use the weighted backends feature. |
| [ERR\_NGROK\_6530](/docs/errors/err_ngrok_6530) | The `ID` header cannot be removed without specifying a replacement. |
| [ERR\_NGROK\_6531](/docs/errors/err_ngrok_6531) | The tunnel group label key/value `ID` may not contain '=' characters. |
| [ERR\_NGROK\_6600](/docs/errors/err_ngrok_6600) | The account `NAME` has reached its team size limit and may not add additional users. |
| [ERR\_NGROK\_6601](/docs/errors/err_ngrok_6601) | Failed to add `USER_NAME` as a member of account `ACCOUNT_NAME` because they are already a member. |
| [ERR\_NGROK\_6602](/docs/errors/err_ngrok_6602) | You may not remove the last administrator of the account. Grant administrator privileges to another member first. |
| [ERR\_NGROK\_6603](/docs/errors/err_ngrok_6603) | Your account is not allowed to set membership permissions. |
| [ERR\_NGROK\_6604](/docs/errors/err_ngrok_6604) | You may not remove an administrator from the account. Only administrators may remove other administrators. |
| [ERR\_NGROK\_6605](/docs/errors/err_ngrok_6605) | You may not grant administrator privileges to an account member. Only administrators may grant administrative privileges. |
| [ERR\_NGROK\_6606](/docs/errors/err_ngrok_6606) | You may not change an administrator's permissions. Only other administrators may make that change. |
| [ERR\_NGROK\_6607](/docs/errors/err_ngrok_6607) | You may not change the account administrator. Only the current account administrator may make this change. |
| [ERR\_NGROK\_6608](/docs/errors/err_ngrok_6608) | Could not transfer administrative control to membership `ID` because it could not be found on this account. |
| [ERR\_NGROK\_6609](/docs/errors/err_ngrok_6609) | Swapping administrators is not supported on accounts with RBAC enabled. |
| [ERR\_NGROK\_6612](/docs/errors/err_ngrok_6612) | You are not allowed to remove members. |
| [ERR\_NGROK\_6613](/docs/errors/err_ngrok_6613) | You are not allowed to create members. |
| [ERR\_NGROK\_6614](/docs/errors/err_ngrok_6614) | You are not allowed to set the permissions of members. |
| [ERR\_NGROK\_6615](/docs/errors/err_ngrok_6615) | You may not create users with higher permissions than your own. |
| [ERR\_NGROK\_6616](/docs/errors/err_ngrok_6616) | You may not set user permissions higher than your own. |
| [ERR\_NGROK\_6617](/docs/errors/err_ngrok_6617) | Users must have a defined billing permission. |
| [ERR\_NGROK\_6618](/docs/errors/err_ngrok_6618) | You are not allowed to create members, this account uses SCIM 2.0 to manage members. |
| [ERR\_NGROK\_6619](/docs/errors/err_ngrok_6619) | You are not allowed to remove members, this account uses SCIM 2.0 to manage members. |
| [ERR\_NGROK\_6620](/docs/errors/err_ngrok_6620) | You are not allowed to activate/deactivate members, this account uses SCIM 2.0 to manage members. |
| [ERR\_NGROK\_6621](/docs/errors/err_ngrok_6621) | You are not allowed to activate/deactivate admins. Only other administrators may make that change. |
| [ERR\_NGROK\_6622](/docs/errors/err_ngrok_6622) | You may not deactivate the last administrator of the account. Grant administrator privileges to another member first. |
| [ERR\_NGROK\_6623](/docs/errors/err_ngrok_6623) | Could not transfer administrative control to membership `ID` because it is deactivated. Activate the member first. |
| [ERR\_NGROK\_6700](/docs/errors/err_ngrok_6700) | The description is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_6701](/docs/errors/err_ngrok_6701) | Metadata is limited to `MAX` characters, but the provided value had `VAL` characters. |
| [ERR\_NGROK\_6702](/docs/errors/err_ngrok_6702) | No DNS records were returned when querying for an NS record for the domain `DOMAIN`. |
| [ERR\_NGROK\_6703](/docs/errors/err_ngrok_6703) | The NS records for the domain `DOMAIN` "`GOT`" do not match the expected targets "`EXPECTED`". |
| [ERR\_NGROK\_6704](/docs/errors/err_ngrok_6704) | The specified domain "`DOMAIN`" is not a valid domain name. Enter a valid DNS name. |
| [ERR\_NGROK\_6705](/docs/errors/err_ngrok_6705) | The agent ingress domain "`DOMAIN`" must be a third party domain, you may not enter a domain controlled by ngrok. |
| [ERR\_NGROK\_6706](/docs/errors/err_ngrok_6706) | The agent ingress domain "`DOMAIN`" already exists, choose another domain. |
| [ERR\_NGROK\_6707](/docs/errors/err_ngrok_6707) | Your account can't reserve custom agent ingresses. |
| [ERR\_NGROK\_6708](/docs/errors/err_ngrok_6708) | Multiple certificate sources provided. |
| [ERR\_NGROK\_6709](/docs/errors/err_ngrok_6709) | Some of the dedicated IPs "`IPS`" are already used in a different agent ingress. |
| [ERR\_NGROK\_6710](/docs/errors/err_ngrok_6710) | Dedicated IP "`IP`" is not a valid IP. |
| [ERR\_NGROK\_6711](/docs/errors/err_ngrok_6711) | Dedicated IP "`IP`" is duplicated in the set of IPs. |
| [ERR\_NGROK\_7000](/docs/errors/err_ngrok_7000) | Edge not found |
| [ERR\_NGROK\_7001](/docs/errors/err_ngrok_7001) | Invalid edge ID |
| [ERR\_NGROK\_7002](/docs/errors/err_ngrok_7002) | Invalid edge request |
| [ERR\_NGROK\_7007](/docs/errors/err_ngrok_7007) | The IP Policy ID `ID` specified for the IP Restriction module does not exist. |
| [ERR\_NGROK\_7008](/docs/errors/err_ngrok_7008) | Edges are deprecated and no longer available. |
| [ERR\_NGROK\_7009](/docs/errors/err_ngrok_7009) | Your account is limited to a maximum of `MAX` edges. |
| [ERR\_NGROK\_7011](/docs/errors/err_ngrok_7011) | Invalid edge, circuit breaker error threshold percentage must be between 0.0 and 1.0 inclusive, was `VAL`. |
| [ERR\_NGROK\_7012](/docs/errors/err_ngrok_7012) | The auth provider `VAL` does not exist. Specify an auth provider ID or the special value 'agent'. |
| [ERR\_NGROK\_7013](/docs/errors/err_ngrok_7013) | The edge module exceeds the max number of IP Policies. You specified `VAL`, the maximum is `MAX`. |
| [ERR\_NGROK\_7014](/docs/errors/err_ngrok_7014) | The edge module TLS CA certificate size exceeds the max. You specified `VAL`, the maximum is `MAX`. |
| [ERR\_NGROK\_7015](/docs/errors/err_ngrok_7015) | The edge module exceeds the max number of headers. You specified `VAL`, the maximum is `MAX`. |
| [ERR\_NGROK\_7016](/docs/errors/err_ngrok_7016) | Invalid edge module, circuit breaker tripped duration must be greater than 0, was `VAL`. |
| [ERR\_NGROK\_7017](/docs/errors/err_ngrok_7017) | Invalid edge module, circuit breaker rolling window must be greater than 0, was `VAL`. |
| [ERR\_NGROK\_7018](/docs/errors/err_ngrok_7018) | Invalid edge module, circuit breaker num buckets must be greater than 0 and less than `MAX`, was `VAL`. |
| [ERR\_NGROK\_7019](/docs/errors/err_ngrok_7019) | The edge could not be deleted because it is still referenced by at least one reserved domain or reserved address. |
| [ERR\_NGROK\_7020](/docs/errors/err_ngrok_7020) | The edge must specify a type. |
| [ERR\_NGROK\_7021](/docs/errors/err_ngrok_7021) | The module `NAME` is not supported on an edge of type `TYPE`. |
| [ERR\_NGROK\_7022](/docs/errors/err_ngrok_7022) | `NAME` is not a valid edge type. Must be one of 'http', 'https', 'tcp'. |
| [ERR\_NGROK\_7023](/docs/errors/err_ngrok_7023) | `KEY` is not a valid HTTP header name because it contains at least one invalid character. |
| [ERR\_NGROK\_7024](/docs/errors/err_ngrok_7024) | `VAL` is not a valid HTTP header value: `REASON`. |
| [ERR\_NGROK\_7025](/docs/errors/err_ngrok_7025) | You must specify at least one IP Policy in the IP Restriction module. |
| [ERR\_NGROK\_7026](/docs/errors/err_ngrok_7026) | SNS webhook verification does not accept a secret. |
| [ERR\_NGROK\_7027](/docs/errors/err_ngrok_7027) | Webhook verification for `T` requires a secret. |
| [ERR\_NGROK\_7028](/docs/errors/err_ngrok_7028) | There were validation errors while saving the edge:`ERRS` |
| [ERR\_NGROK\_7029](/docs/errors/err_ngrok_7029) | You must specify a supported provider name. Supported providers: \[`T`] |
| [ERR\_NGROK\_7030](/docs/errors/err_ngrok_7030) | Webhook provider `T` is not supported. Supported providers: \[`TYPE`] |
| [ERR\_NGROK\_7031](/docs/errors/err_ngrok_7031) | Your account is not authorized to use webhook verification. |
| [ERR\_NGROK\_7032](/docs/errors/err_ngrok_7032) | You may not configure the TLS termination parameter `PARAMETER` when the HTTPS module disables TLS termination. |
| [ERR\_NGROK\_7033](/docs/errors/err_ngrok_7033) | Invalid edge module, unmanaged provider configurations must specify a client ID and a client secret. |
| [ERR\_NGROK\_7034](/docs/errors/err_ngrok_7034) | Invalid edge module, custom OAuth scopes on a managed OAuth application are not allowed. Define a custom OAuth application to use custom scopes. |
| [ERR\_NGROK\_7035](/docs/errors/err_ngrok_7035) | Invalid edge module, OAuth auth check interval must be at least `MIN`, was `ACTUAL`. |
| [ERR\_NGROK\_7036](/docs/errors/err_ngrok_7036) | Invalid edge module, OAuth may only have one provider configuration but multiple are defined: \[`PROVIDER_NAMES`]. |
| [ERR\_NGROK\_7037](/docs/errors/err_ngrok_7037) | Invalid edge module, OAuth does not define any provider configurations but one is required. |
| [ERR\_NGROK\_7038](/docs/errors/err_ngrok_7038) | Invalid edge module, OAuth provider `PROVIDER` requires at least the `SCOPE` scope to authenticate by `AUTH_FEATURE`.' |
| [ERR\_NGROK\_7039](/docs/errors/err_ngrok_7039) | Invalid edge module, OAuth provider `PROVIDER` contains an invalid email domain: `NAME`. |
| [ERR\_NGROK\_7040](/docs/errors/err_ngrok_7040) | Invalid edge module, OAuth GitHub Teams must be listed as either numerical ids or in the format 'org\_slug/team\_slug', `TEAM` does not match either format. |
| [ERR\_NGROK\_7041](/docs/errors/err_ngrok_7041) | Your account is not authorized to use OAuth. |
| [ERR\_NGROK\_7042](/docs/errors/err_ngrok_7042) | Invalid edge module, OAuth cookie prefix `PREFIX` must consist of only alphanumeric characters with periods. |
| [ERR\_NGROK\_7043](/docs/errors/err_ngrok_7043) | Invalid edge module, OAuth provider `PROVIDER` contains an invalid email address, `NAME`. |
| [ERR\_NGROK\_7044](/docs/errors/err_ngrok_7044) | Invalid edge module, OAuth provider `PROVIDER` contains an email domain with invalid punycode: `NAME`. |
| [ERR\_NGROK\_7045](/docs/errors/err_ngrok_7045) | Invalid edge module, OAuth provider `PROVIDER` contains an email address with invalid punycode: `NAME`. |
| [ERR\_NGROK\_7046](/docs/errors/err_ngrok_7046) | Invalid edge module, OAuth provider `PROVIDER` email addresses must be unique, but a duplicate is present: `DUPLICATE`. |
| [ERR\_NGROK\_7047](/docs/errors/err_ngrok_7047) | Invalid edge module, OAuth provider `PROVIDER` email domains must be unique, but a duplicate is present: `DUPLICATE`. |
| [ERR\_NGROK\_7048](/docs/errors/err_ngrok_7048) | Invalid edge module, OAuth provider `PROVIDER` teams must be unique, but a duplicate is present: `DUPLICATE`. |
| [ERR\_NGROK\_7049](/docs/errors/err_ngrok_7049) | Invalid edge module, OAuth provider `PROVIDER` organizations must be unique, but a duplicate is present: `DUPLICATE`. |
| [ERR\_NGROK\_7050](/docs/errors/err_ngrok_7050) | Invalid edge module, OAuth provider `PROVIDER` groups must be unique, but a duplicate is present: `DUPLICATE`. |
| [ERR\_NGROK\_7051](/docs/errors/err_ngrok_7051) | Invalid edge module, OAuth provider `PROVIDER` email addresses must not contain empty values |
| [ERR\_NGROK\_7052](/docs/errors/err_ngrok_7052) | Invalid edge module, OAuth provider `PROVIDER` email domains must not contain empty values |
| [ERR\_NGROK\_7053](/docs/errors/err_ngrok_7053) | Invalid edge module, OAuth provider `PROVIDER` teams must not contain empty values |
| [ERR\_NGROK\_7054](/docs/errors/err_ngrok_7054) | Invalid edge module, OAuth provider `PROVIDER` organizations must not contain empty values |
| [ERR\_NGROK\_7055](/docs/errors/err_ngrok_7055) | Invalid edge module, OAuth provider `PROVIDER` groups must not contain empty values |
| [ERR\_NGROK\_7056](/docs/errors/err_ngrok_7056) | The edge module exceeds the maximum number of OAuth scopes. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_7057](/docs/errors/err_ngrok_7057) | The edge module exceeds the maximum number of OAuth GitHub teams. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_7058](/docs/errors/err_ngrok_7058) | The edge module exceeds the maximum number of OAuth GitHub orgs. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_7059](/docs/errors/err_ngrok_7059) | The edge module exceeds the maximum number of OAuth Google groups. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_7060](/docs/errors/err_ngrok_7060) | The edge module exceeds the maximum number of OAuth emails. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_7061](/docs/errors/err_ngrok_7061) | The edge module exceeds the maximum number of OAuth domains. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_7062](/docs/errors/err_ngrok_7062) | The edge specifies the following modules which may not be enabled when TLS is not terminated: `MODULE_NAMES`. |
| [ERR\_NGROK\_7067](/docs/errors/err_ngrok_7067) | Invalid edge module, email addresses must be lowercase but `EMAIL` is not. |
| [ERR\_NGROK\_7068](/docs/errors/err_ngrok_7068) | Invalid edge module, email domains must be lowercase but `DOMAIN` is not. |
| [ERR\_NGROK\_7069](/docs/errors/err_ngrok_7069) | Duplicate 'add' header, `HEADER` was provided twice with different casings: `CASE_ONE` and `CASE_TWO`. |
| [ERR\_NGROK\_7070](/docs/errors/err_ngrok_7070) | Your account is limited to `MAX` edges. |
| [ERR\_NGROK\_7071](/docs/errors/err_ngrok_7071) | Your account is rate limited for adding `MAX` edges per `INTERVAL`. |
| [ERR\_NGROK\_7072](/docs/errors/err_ngrok_7072) | The CA ID `ID` specified for the Mutual TLS module does not exist. |
| [ERR\_NGROK\_7073](/docs/errors/err_ngrok_7073) | Description is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_7074](/docs/errors/err_ngrok_7074) | Metadata is limited to `MAX` characters; you have entered `VAL` characters. |
| [ERR\_NGROK\_7075](/docs/errors/err_ngrok_7075) | The Mutual TLS configurations exceeds the limit of `LIMIT` attached certificate authorities. |
| [ERR\_NGROK\_7079](/docs/errors/err_ngrok_7079) | The edge specifies conflicting authentication modules. Only one of SAML, OIDC, or OAuth may be enabled. |
| [ERR\_NGROK\_7080](/docs/errors/err_ngrok_7080) | The SAML metadata exceeds the maximum length of `MAX` bytes, got `NBYTES`. |
| [ERR\_NGROK\_7081](/docs/errors/err_ngrok_7081) | You must specify only the SAML IdP metadata or the SAML IdP metadata URL, but not both. |
| [ERR\_NGROK\_7082](/docs/errors/err_ngrok_7082) | Failed to connect to IdP metadata URL `MDURL`: `ERR`. |
| [ERR\_NGROK\_7083](/docs/errors/err_ngrok_7083) | Failed to parse the SAML IdP metadata: `ERR`. |
| [ERR\_NGROK\_7084](/docs/errors/err_ngrok_7084) | Received unexpected status code `STATUSCODE` while fetching metadata URL `MDURL` |
| [ERR\_NGROK\_7085](/docs/errors/err_ngrok_7085) | Failed to parse the SAML IdP metadata fetched from URL `MDURL`: `ERR`. |
| [ERR\_NGROK\_7086](/docs/errors/err_ngrok_7086) | Encountered an error while reading the response body from the IdP metadata URL `MDURL`: `ERR`. |
| [ERR\_NGROK\_7087](/docs/errors/err_ngrok_7087) | The specified OIDC issuer has a maximum length of `MAX` bytes. The specified value is `N` bytes. |
| [ERR\_NGROK\_7088](/docs/errors/err_ngrok_7088) | The OIDC issuer property is required. |
| [ERR\_NGROK\_7089](/docs/errors/err_ngrok_7089) | The OIDC Client ID property is required. |
| [ERR\_NGROK\_7090](/docs/errors/err_ngrok_7090) | The OIDC Client Secret property is required. |
| [ERR\_NGROK\_7091](/docs/errors/err_ngrok_7091) | One of the SAML IdP Metadata or IdP Metadata URL properties must be specified. |
| [ERR\_NGROK\_7092](/docs/errors/err_ngrok_7092) | Invalid edge module, session inactivity timeout cannot be more than one year, was `ACTUAL`. |
| [ERR\_NGROK\_7093](/docs/errors/err_ngrok_7093) | Your account is not authorized to use basic auth. |
| [ERR\_NGROK\_7094](/docs/errors/err_ngrok_7094) | Your account is not authorized to use compression. |
| [ERR\_NGROK\_7095](/docs/errors/err_ngrok_7095) | Your account is not authorized to use circuit breaker. |
| [ERR\_NGROK\_7096](/docs/errors/err_ngrok_7096) | Your account is not authorized to use request headers. |
| [ERR\_NGROK\_7097](/docs/errors/err_ngrok_7097) | Your account is not authorized to use response headers. |
| [ERR\_NGROK\_7098](/docs/errors/err_ngrok_7098) | Your account is not authorized to use OIDC. |
| [ERR\_NGROK\_7099](/docs/errors/err_ngrok_7099) | Your account is not authorized to use SAML. |
| [ERR\_NGROK\_7100](/docs/errors/err_ngrok_7100) | Your account is not authorized to use TLS termination. |
| [ERR\_NGROK\_7101](/docs/errors/err_ngrok_7101) | Your account is not authorized to use IP Restrictions. |
| [ERR\_NGROK\_7102](/docs/errors/err_ngrok_7102) | Your account is not authorized to use TCP address backends. |
| [ERR\_NGROK\_7103](/docs/errors/err_ngrok_7103) | Your account is not authorized to use mutual TLS. |
| [ERR\_NGROK\_7104](/docs/errors/err_ngrok_7104) | Edge has invalid hostports, must be specified in the format 'hostname:portnumber': `INVALID` |
| [ERR\_NGROK\_7105](/docs/errors/err_ngrok_7105) | The header beginning with `PREFIX`...' exceeds the maximum header name length of `BYTES` bytes. |
| [ERR\_NGROK\_7106](/docs/errors/err_ngrok_7106) | The header value for `HEADERKEY` beginning with `PREFIX`...' exceeds the maximum header value length of `BYTES` bytes. |
| [ERR\_NGROK\_7107](/docs/errors/err_ngrok_7107) | The sendgrid verification key is not a base64 encoded ecdsa public key. The following error was encountered while trying to parse it: "`ERROR`" |
| [ERR\_NGROK\_7108](/docs/errors/err_ngrok_7108) | Your account is not authorized to use the websocket to TCP converter. |
| [ERR\_NGROK\_7109](/docs/errors/err_ngrok_7109) | You may not configure the TLS termination parameter 'terminate\_at' for an HTTPS edge. |
| [ERR\_NGROK\_7110](/docs/errors/err_ngrok_7110) | The request edge ID `EID` does not match the route edge ID `REID`. |
| [ERR\_NGROK\_7111](/docs/errors/err_ngrok_7111) | The edge hostport `HOST`:`PORT` does not exist. |
| [ERR\_NGROK\_7112](/docs/errors/err_ngrok_7112) | The hostport `HOSTPORT` has port out of range: `PORT` is not in range 1-65535. |
| [ERR\_NGROK\_7113](/docs/errors/err_ngrok_7113) | The address `HOSTPORT` is not reserved. |
| [ERR\_NGROK\_7114](/docs/errors/err_ngrok_7114) | The address `HOSTPORT` is not reserved by your account. |
| [ERR\_NGROK\_7115](/docs/errors/err_ngrok_7115) | The address `HOSTPORT` has an endpoint configuration which must be removed before it can be used by an edge. |
| [ERR\_NGROK\_7116](/docs/errors/err_ngrok_7116) | The domain `HOSTPORT` is unsupported because it does not use port 443. |
| [ERR\_NGROK\_7117](/docs/errors/err_ngrok_7117) | The domain `HOSTPORT` is not reserved. |
| [ERR\_NGROK\_7118](/docs/errors/err_ngrok_7118) | The domain `HOSTPORT` is not reserved by your account. |
| [ERR\_NGROK\_7119](/docs/errors/err_ngrok_7119) | The domain `HOSTPORT` has an endpoint configuration which must be removed before it can be used by an edge. |
| [ERR\_NGROK\_7120](/docs/errors/err_ngrok_7120) | TCP edges can only be associated with TCP addresses: `HOSTPORT` is a domain. |
| [ERR\_NGROK\_7121](/docs/errors/err_ngrok_7121) | HTTPS edges can only be associated with reserved domains: `HOSTPORT` is a TCP address. |
| [ERR\_NGROK\_7122](/docs/errors/err_ngrok_7122) | Hostport `HOSTPORT` already exists for another edge. |
| [ERR\_NGROK\_7123](/docs/errors/err_ngrok_7123) | Edge routes require a match expression. |
| [ERR\_NGROK\_7124](/docs/errors/err_ngrok_7124) | The edge route `ID` could not be found. |
| [ERR\_NGROK\_7125](/docs/errors/err_ngrok_7125) | There is a duplicate route `ID` for HTTPS edge. |
| [ERR\_NGROK\_7126](/docs/errors/err_ngrok_7126) | Route match expression `MATCH` must be unique across all routes for HTTPS edge. |
| [ERR\_NGROK\_7127](/docs/errors/err_ngrok_7127) | OAuth may not currently be configured for any route except '/', could not configure for route `MATCH`. |
| [ERR\_NGROK\_7128](/docs/errors/err_ngrok_7128) | Your account is limited to a maximum of `MAX` routes for a single edge. |
| [ERR\_NGROK\_7129](/docs/errors/err_ngrok_7129) | Your account is limited to a maximum of `MAX` hostports for a single edge. |
| [ERR\_NGROK\_7130](/docs/errors/err_ngrok_7130) | Invalid match type, valid values are "exact\_path" and "path\_prefix". |
| [ERR\_NGROK\_7131](/docs/errors/err_ngrok_7131) | The route selector expression `MATCH` is invalid. Valid route selector match expressions are of the form /path (e.g. "/foo", or "/foo/bar"). |
| [ERR\_NGROK\_7132](/docs/errors/err_ngrok_7132) | The hostport `HOSTPORT` is already in use by an agent directly. |
| [ERR\_NGROK\_7133](/docs/errors/err_ngrok_7133) | TLS edges can only be associated with reserved domains: `HOSTPORT` is a TCP address. |
| [ERR\_NGROK\_7134](/docs/errors/err_ngrok_7134) | OAuth, OIDC and SAML may only be configured for routes with path selectors (i.e. 'exact\_path', 'path\_prefix'). |
| [ERR\_NGROK\_7135](/docs/errors/err_ngrok_7135) | The route selector expression exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7136](/docs/errors/err_ngrok_7136) | The OAuth Cookie Prefix exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7137](/docs/errors/err_ngrok_7137) | The OAuth Client ID exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7138](/docs/errors/err_ngrok_7138) | The OAuth Client Secret exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7139](/docs/errors/err_ngrok_7139) | The OAuth Email Address exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7140](/docs/errors/err_ngrok_7140) | The OAuth Email Domain exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7141](/docs/errors/err_ngrok_7141) | The OAuth Scope exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7142](/docs/errors/err_ngrok_7142) | The edge module exceeds the maximum number of GitHub teams. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_7143](/docs/errors/err_ngrok_7143) | The edge module exceeds the maximum number of GitHub orgs. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_7144](/docs/errors/err_ngrok_7144) | The OAuth GitHub team exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7145](/docs/errors/err_ngrok_7145) | The OAuth GitHub org exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7146](/docs/errors/err_ngrok_7146) | The edge module exceeds the maximum number of Google groups. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_7147](/docs/errors/err_ngrok_7147) | The OAuth Google group exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7148](/docs/errors/err_ngrok_7148) | The OIDC Client ID exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7149](/docs/errors/err_ngrok_7149) | The OIDC Client Secret exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7150](/docs/errors/err_ngrok_7150) | The edge module exceeds the maximum number of OIDC scopes. You specified `COUNT`, the max is `MAX`. |
| [ERR\_NGROK\_7151](/docs/errors/err_ngrok_7151) | The OIDC Scope exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7152](/docs/errors/err_ngrok_7152) | The OIDC Authn URL exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7153](/docs/errors/err_ngrok_7153) | The OIDC cookie prefix exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7154](/docs/errors/err_ngrok_7154) | The Webhook Verification secret exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_7155](/docs/errors/err_ngrok_7155) | Enabling OAuth, OIDC, or SAML on more than one route is not supported. |
| [ERR\_NGROK\_7158](/docs/errors/err_ngrok_7158) | Invalid edge module, OAuth auth check interval must be no greater than `MAX`, was `ACTUAL`. |
| [ERR\_NGROK\_7159](/docs/errors/err_ngrok_7159) | Invalid edge module, OIDC auth check interval must be at least `MIN`, was `ACTUAL`. |
| [ERR\_NGROK\_7160](/docs/errors/err_ngrok_7160) | Invalid edge module, OIDC auth check interval must be no greater than `MAX`, was `ACTUAL`. |
| [ERR\_NGROK\_7161](/docs/errors/err_ngrok_7161) | Invalid edge module, OAuth max session duration must be no greater than `MAX`, was `ACTUAL`. |
| [ERR\_NGROK\_7162](/docs/errors/err_ngrok_7162) | Invalid edge module, OIDC max session duration must be no greater than `MAX`, was `ACTUAL`. |
| [ERR\_NGROK\_7163](/docs/errors/err_ngrok_7163) | Your account is not authorized to use the TLS edges. |
| [ERR\_NGROK\_7164](/docs/errors/err_ngrok_7164) | The `ID` header cannot be removed without specifying a replacement. |
| [ERR\_NGROK\_7165](/docs/errors/err_ngrok_7165) | An unsupported OAuth Provider was configured. |
| [ERR\_NGROK\_7166](/docs/errors/err_ngrok_7166) | The "`PROVIDER`" OAuth Provider does not currently have a managed app available, specify a client id and client secret. |
| [ERR\_NGROK\_7167](/docs/errors/err_ngrok_7167) | Your account is not authorized to use user agent filter. |
| [ERR\_NGROK\_7168](/docs/errors/err_ngrok_7168) | Your account is not authorized to use JWT Validation. |
| [ERR\_NGROK\_7169](/docs/errors/err_ngrok_7169) | The `TYPE` token type is invalid. Valid values are 'jwt', 'at+jwt', and 'it+jwt'. |
| [ERR\_NGROK\_7170](/docs/errors/err_ngrok_7170) | The `METHOD` token method is invalid. Valid values are 'header' and 'body'. |
| [ERR\_NGROK\_7171](/docs/errors/err_ngrok_7171) | The JWT Validation configuration is invalid: `DETAIL`. |
| [ERR\_NGROK\_7172](/docs/errors/err_ngrok_7172) | The JWT Validation configuration must have at least one issuer in the allow list. |
| [ERR\_NGROK\_7173](/docs/errors/err_ngrok_7173) | The JWT Validation issuer is invalid: `ISSUER` is not a valid URL. |
| [ERR\_NGROK\_7174](/docs/errors/err_ngrok_7174) | The JWT Validation configuration must have at least one audience in the allow list. |
| [ERR\_NGROK\_7175](/docs/errors/err_ngrok_7175) | The JWT Validation audience is invalid: `MSG`. |
| [ERR\_NGROK\_7176](/docs/errors/err_ngrok_7176) | The JWT Validation configuration must have at least one allowed algorithm. |
| [ERR\_NGROK\_7177](/docs/errors/err_ngrok_7177) | The `TYPE` algorithm is invalid. Consult the documentation for valid algorithms. |
| [ERR\_NGROK\_7178](/docs/errors/err_ngrok_7178) | The JWT Validation configuration must have at least one token configuration. |
| [ERR\_NGROK\_7179](/docs/errors/err_ngrok_7179) | The JWT Validation http token is invalid: `MSG`. |
| [ERR\_NGROK\_7180](/docs/errors/err_ngrok_7180) | The JWT Validation http token name `NAME` is invalid. |
| [ERR\_NGROK\_7181](/docs/errors/err_ngrok_7181) | The JWT Validation http token prefix `PREFIX` is invalid. |
| [ERR\_NGROK\_7182](/docs/errors/err_ngrok_7182) | The JWT Validation signing key must have a way to be identified such as the 'kid' token claim. |
| [ERR\_NGROK\_7183](/docs/errors/err_ngrok_7183) | The JWT Validation signing key must have a valid identification mechanism such as the 'kid' token claim. |
| [ERR\_NGROK\_7184](/docs/errors/err_ngrok_7184) | The JWT Validation signing key must have at least one source. |
| [ERR\_NGROK\_7185](/docs/errors/err_ngrok_7185) | The JWT Validation signing key source has an invalid additional jku: `JKU` is not a valid URL. |
| [ERR\_NGROK\_7186](/docs/errors/err_ngrok_7186) | The JWT Validation signing key source has an invalid additional jku: `JKU` did not serve a JWKS. |
| [ERR\_NGROK\_7187](/docs/errors/err_ngrok_7187) | The JWT Validation issuer `ISSUER` must be unique. Make sure to include it only once in the allow list. |
| [ERR\_NGROK\_7188](/docs/errors/err_ngrok_7188) | The JWT Validation audience `AUDIENCE` must be unique. Make sure to include it only once in the allow list. |
| [ERR\_NGROK\_7189](/docs/errors/err_ngrok_7189) | The JWT Validation http token identified by the method: `METHOD` and name: `NAME` must be unique. Make sure to include it only once in the token list. |
| [ERR\_NGROK\_7190](/docs/errors/err_ngrok_7190) | The JWT Validation signing key algorithm `ALGORITHM` must be unique. Make sure to include it only once in the allowed algorithms list. |
| [ERR\_NGROK\_7191](/docs/errors/err_ngrok_7191) | The JWT Validation signing key identification token claim `CLAIM` must be unique. Make sure to include it only once in the token claim list. |
| [ERR\_NGROK\_7192](/docs/errors/err_ngrok_7192) | The JWT Validation signing key source additional jku `JKU` must be unique. Make sure to include it only once in the additional jku list. |
| [ERR\_NGROK\_7193](/docs/errors/err_ngrok_7193) | The JWT Validation signing key sources have too many possible sources. You can supply at most 100. |
| [ERR\_NGROK\_7194](/docs/errors/err_ngrok_7194) | Your account is not authorized to use policies. |
| [ERR\_NGROK\_7195](/docs/errors/err_ngrok_7195) | This edge module has exceeded its policy rule limit of `LIMIT`. Log into [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) to view your options. |
| [ERR\_NGROK\_7196](/docs/errors/err_ngrok_7196) | Your account has read-only access to Edges. |
| [ERR\_NGROK\_8000](/docs/errors/err_ngrok_8000) | Failed to resolve host `HOST`: `ERR` |
| [ERR\_NGROK\_8001](/docs/errors/err_ngrok_8001) | Failed to establish internet connectivity: `ERR` |
| [ERR\_NGROK\_8002](/docs/errors/err_ngrok_8002) | Failed to establish TCP connection to `HOST` with error: `ERR` |
| [ERR\_NGROK\_8003](/docs/errors/err_ngrok_8003) | Failed to establish TLS connection to `HOST` with error: `ERR`. Possible Man-in-the Middle. |
| [ERR\_NGROK\_8004](/docs/errors/err_ngrok_8004) | Failed to establish tunnel protocol connection to `HOST` with error: `ERR` |
| [ERR\_NGROK\_8005](/docs/errors/err_ngrok_8005) | Failed to resolve proxy IP with error: `ERR` |
| [ERR\_NGROK\_8006](/docs/errors/err_ngrok_8006) | Failed to connect to proxy `URL` with error: `ERR` |
| [ERR\_NGROK\_8007](/docs/errors/err_ngrok_8007) | No tunnel servers were reachable via TCP. |
| [ERR\_NGROK\_8008](/docs/errors/err_ngrok_8008) | No tunnel servers could establish a TLS connection. |
| [ERR\_NGROK\_8009](/docs/errors/err_ngrok_8009) | No tunnel servers could establish a tunnel connection. |
| [ERR\_NGROK\_8010](/docs/errors/err_ngrok_8010) | `RESOLVER` was the only resolver to return `IP` for the hostname `HOSTNAME`. This, or the other resolvers, may be returning incorrect results. |
| [ERR\_NGROK\_8011](/docs/errors/err_ngrok_8011) | IPV6 errors encountered - it may be disabled. |
| [ERR\_NGROK\_8012](/docs/errors/err_ngrok_8012) | Traffic successfully made it to the ngrok agent, but the agent failed to establish a connection to the upstream web service at `ADDR`. |
| [ERR\_NGROK\_8013](/docs/errors/err_ngrok_8013) | You must add a credit or debit card before you can use TCP endpoints on a free account. We require a valid card as a way to combat abuse and keep the internet a safe place. This card will NOT be charged. |
| [ERR\_NGROK\_8014](/docs/errors/err_ngrok_8014) | Your agent has been blocked from connecting to ngrok because it has been suspected of violating our Acceptable Use policy: [https://ngrok.com/tos](https://ngrok.com/tos) Your actions have been reported to our security team. |
| [ERR\_NGROK\_9000](/docs/errors/err_ngrok_9000) | An account is required to use basic authentication. |
| [ERR\_NGROK\_9001](/docs/errors/err_ngrok_9001) | Your account is not authorized to use compression. |
| [ERR\_NGROK\_9002](/docs/errors/err_ngrok_9002) | Your account is not authorized to use circuit breaker. |
| [ERR\_NGROK\_9003](/docs/errors/err_ngrok_9003) | Your legacy account is not authorized to use request headers. |
| [ERR\_NGROK\_9004](/docs/errors/err_ngrok_9004) | Your legacy account is not authorized to use response headers. |
| [ERR\_NGROK\_9005](/docs/errors/err_ngrok_9005) | Your legacy account is not authorized to use OIDC. |
| [ERR\_NGROK\_9006](/docs/errors/err_ngrok_9006) | Your legacy account is not authorized to use SAML. |
| [ERR\_NGROK\_9007](/docs/errors/err_ngrok_9007) | Your legacy account is not authorized to use TLS Termination. |
| [ERR\_NGROK\_9008](/docs/errors/err_ngrok_9008) | Your legacy account is not authorized to run the agent as a service. |
| [ERR\_NGROK\_9009](/docs/errors/err_ngrok_9009) | Running the agent with an http/s proxy is a Pay-as-you-go feature. If this is unexpected, verify that there is no proxy\_url value in your ngrok configuration file and that the http\_proxy environment variable is not set. |
| [ERR\_NGROK\_9010](/docs/errors/err_ngrok_9010) | Your legacy account is not authorized to run the agent with socks5 proxy. |
| [ERR\_NGROK\_9011](/docs/errors/err_ngrok_9011) | Your legacy account is not authorized to run the agent on a custom network interface. |
| [ERR\_NGROK\_9012](/docs/errors/err_ngrok_9012) | Your legacy account is not authorized to run the agent with custom CAs. |
| [ERR\_NGROK\_9013](/docs/errors/err_ngrok_9013) | Your legacy account is not authorized to run the agent with mutual TLS. |
| [ERR\_NGROK\_9014](/docs/errors/err_ngrok_9014) | Your legacy account is not authorized to run the agent with proxy proto. |
| [ERR\_NGROK\_9015](/docs/errors/err_ngrok_9015) | Your account is not authorized to use OAuth. |
| [ERR\_NGROK\_9016](/docs/errors/err_ngrok_9016) | Your account is not authorized to use webhook verification. |
| [ERR\_NGROK\_9017](/docs/errors/err_ngrok_9017) | Your legacy account is not authorized to use ip restrictions. |
| [ERR\_NGROK\_9018](/docs/errors/err_ngrok_9018) | An account is required to use host header rewrite. |
| [ERR\_NGROK\_9019](/docs/errors/err_ngrok_9019) | Your legacy account is not authorized to use mutual TLS. |
| [ERR\_NGROK\_9020](/docs/errors/err_ngrok_9020) | Your legacy account is not authorized to use the websocket to TCP converter. |
| [ERR\_NGROK\_9021](/docs/errors/err_ngrok_9021) | You may specify at most one of subdomain, hostname, or domain for a tunnel. |
| [ERR\_NGROK\_9022](/docs/errors/err_ngrok_9022) | Your legacy account is not authorized to use user agent filtering. |
| [ERR\_NGROK\_9023](/docs/errors/err_ngrok_9023) | Your account is not authorized to use the policy module. |
| [ERR\_NGROK\_9024](/docs/errors/err_ngrok_9024) | The account `ACCOUNT` is not authorized to use the requested leg number `LEG`. |
| [ERR\_NGROK\_9025](/docs/errors/err_ngrok_9025) | You cannot specify both "Policy" and "TrafficPolicy". Use "TrafficPolicy" as "Policy" is deprecated. |
| [ERR\_NGROK\_9026](/docs/errors/err_ngrok_9026) | The TrafficPolicy you provided is invalid: `ERROR`. |
| [ERR\_NGROK\_9027](/docs/errors/err_ngrok_9027) | Your account is not authorized to use internal bindings. |
| [ERR\_NGROK\_9028](/docs/errors/err_ngrok_9028) | You must specify a domain name for a internally bound endpoint. |
| [ERR\_NGROK\_9029](/docs/errors/err_ngrok_9029) | Failed to start endpoint with `URL`. Endpoints with a "internal" binding must have a url that ends in one of: `SUFFIXES`. |
| [ERR\_NGROK\_9030](/docs/errors/err_ngrok_9030) | Failed to start endpoint with URL `URL`, invalid port. Port must be in range range 1-65535. |
| [ERR\_NGROK\_9031](/docs/errors/err_ngrok_9031) | Failed to start endpoint with URL `URL`. Endpoints must have at most `MAX` parts, but had `DEPTH`. |
| [ERR\_NGROK\_9032](/docs/errors/err_ngrok_9032) | Provided domain `DOMAIN` could not be parsed: `ERROR`. |
| [ERR\_NGROK\_9033](/docs/errors/err_ngrok_9033) | Provided domain `DOMAIN` had a non-numeric port component. |
| [ERR\_NGROK\_9034](/docs/errors/err_ngrok_9034) | Malformed URL: `ERRMSG`. |
| [ERR\_NGROK\_9035](/docs/errors/err_ngrok_9035) | Invalid port for URL with scheme `CURRENTSCHEME`, allowed ports are `WANTPORT`. |
| [ERR\_NGROK\_9036](/docs/errors/err_ngrok_9036) | Invalid scheme `UNSUPPORTEDSCHEME`, allowed schemes: `ALLOWEDSCHEMES`. |
| [ERR\_NGROK\_9037](/docs/errors/err_ngrok_9037) | Invalid URL `URL`, `PARTNAME` `PART` is not allowed. |
| [ERR\_NGROK\_9038](/docs/errors/err_ngrok_9038) | Invalid URL, trailing '/' is not allowed. Did you mean `URLWITHOUTPATH`? |
| [ERR\_NGROK\_9039](/docs/errors/err_ngrok_9039) | You must specify a domain name for a kubernetes operator bound endpoint. |
| [ERR\_NGROK\_9040](/docs/errors/err_ngrok_9040) | We do not allow agents to connect to ngrok from your IP address (`IP`). |
| [ERR\_NGROK\_9041](/docs/errors/err_ngrok_9041) | Supported protocols for kubernetes-bound endpoints are http, tls, and tcp. You provided `PROTO`. |
| [ERR\_NGROK\_9042](/docs/errors/err_ngrok_9042) | TLS endpoints cannot be created on this version of the ngrok agent due to a vulnerability. Upgrade your agent to version 3.24.0 or later |
| [ERR\_NGROK\_9043](/docs/errors/err_ngrok_9043) | HTTP endpoints are restricted for HIPAA-compliant accounts. Use HTTPS instead! |
| [ERR\_NGROK\_10077](/docs/errors/err_ngrok_10077) | This account does not support JIT provisioning for SSO users. |
| [ERR\_NGROK\_10078](/docs/errors/err_ngrok_10078) | This account requires users to be authenticated with a valid SSO provider. |
| [ERR\_NGROK\_10080](/docs/errors/err_ngrok_10080) | The invitation `INVITE_ID` was not found |
| [ERR\_NGROK\_10081](/docs/errors/err_ngrok_10081) | You must specify only the correct ID for the requested team member entry. |
| [ERR\_NGROK\_10082](/docs/errors/err_ngrok_10082) | You must specify a user, bot, or membership ID when attempting to update a credentials owner. |
| [ERR\_NGROK\_10083](/docs/errors/err_ngrok_10083) | You already have a valid MFA configuration of this type enabled. |
| [ERR\_NGROK\_10084](/docs/errors/err_ngrok_10084) | You cannot delete the SSO Identity Provider you used to logged when SSO Enforcement is enabled on your account. |
| [ERR\_NGROK\_10085](/docs/errors/err_ngrok_10085) | The endpoint of the request you are trying to replay was not found. |
| [ERR\_NGROK\_10086](/docs/errors/err_ngrok_10086) | You have exceeded the rate limit of `MAX` replay requests per `INTERVAL`. |
| [ERR\_NGROK\_10087](/docs/errors/err_ngrok_10087) | Request header "`HEADER_NAME`" value too large. |
| [ERR\_NGROK\_10088](/docs/errors/err_ngrok_10088) | Request body size too large. |
| [ERR\_NGROK\_10089](/docs/errors/err_ngrok_10089) | Failed to replay the request. |
| [ERR\_NGROK\_10090](/docs/errors/err_ngrok_10090) | The request you are trying to view was not found. |
| [ERR\_NGROK\_10091](/docs/errors/err_ngrok_10091) | The usage page has timed out. Refresh the page and try again. |
| [ERR\_NGROK\_10092](/docs/errors/err_ngrok_10092) | The replay request's X-Account-Id header is missing or does not match the authenticated account. |
| [ERR\_NGROK\_10093](/docs/errors/err_ngrok_10093) | `REASON` |
| [ERR\_NGROK\_10094](/docs/errors/err_ngrok_10094) | `REASON` |
| [ERR\_NGROK\_10095](/docs/errors/err_ngrok_10095) | The client IP filter value `VALUE` is not an IP address that can match a request. |
| [ERR\_NGROK\_10096](/docs/errors/err_ngrok_10096) | The `FIELD` filter is too large. Filter on at most `LIMIT`. |
| [ERR\_NGROK\_10097](/docs/errors/err_ngrok_10097) | The path filter value cannot match a request path: `REASON`. |
| [ERR\_NGROK\_10098](/docs/errors/err_ngrok_10098) | The sign-in state is invalid or expired. Restart the sign-in flow and try again. |
| [ERR\_NGROK\_10099](/docs/errors/err_ngrok_10099) | SSO is not authorized for this email domain. Contact your administrator or ngrok support if you believe this is a mistake. |
| [ERR\_NGROK\_10100](/docs/errors/err_ngrok_10100) | Just-in-Time provisioning now requires Domain Control. Contact ngrok support at [support@ngrok.com](mailto:support@ngrok.com). |
| [ERR\_NGROK\_10101](/docs/errors/err_ngrok_10101) | Signup domains need the Identity & Access Governance Suite add-on. Add it to your plan at [https://dashboard.ngrok.com/legacy/billing/subscription/add-ons](https://dashboard.ngrok.com/legacy/billing/subscription/add-ons), then request your domain again. |
| [ERR\_NGROK\_10102](/docs/errors/err_ngrok_10102) | Signup domains send new users to your SSO identity provider. Set one up at [https://dashboard.ngrok.com/settings/auth](https://dashboard.ngrok.com/settings/auth), then request your domain again. |
| [ERR\_NGROK\_10103](/docs/errors/err_ngrok_10103) | Enter a valid domain name, like example.com, then request your domain again. |
| [ERR\_NGROK\_10104](/docs/errors/err_ngrok_10104) | Signup domains aren't available on this account. Contact ngrok support at [support@ngrok.com](mailto:support@ngrok.com) to enable them. |
| [ERR\_NGROK\_10105](/docs/errors/err_ngrok_10105) | Your signup domain request is `COUNT` characters, and the limit is `LIMIT`. Shorten the additional information, then request your domain again. |
| [ERR\_NGROK\_10106](/docs/errors/err_ngrok_10106) | Signup domain requests aren't available right now. Contact ngrok support at [support@ngrok.com](mailto:support@ngrok.com) to request your domain. |
| [ERR\_NGROK\_10107](/docs/errors/err_ngrok_10107) | Something went wrong and we didn't record your signup domain request. Request your domain again, or contact ngrok support at [support@ngrok.com](mailto:support@ngrok.com). |
| [ERR\_NGROK\_14000](/docs/errors/err_ngrok_14000) | The `ID` header cannot be removed without specifying a replacement. |
| [ERR\_NGROK\_14001](/docs/errors/err_ngrok_14001) | Got an invalid TLS key/cert pair for TLS termination: `ERR` |
| [ERR\_NGROK\_14002](/docs/errors/err_ngrok_14002) | The PEM data provided for mutual TLS could not be parsed as a certificate: `ERROR`. |
| [ERR\_NGROK\_15000](/docs/errors/err_ngrok_15000) | You are not allowed to create endpoints with subdomains on `BASE`. Your account is on the `PLAN` plan, which doesn't allow starting endpoints on `BASE`. |
| [ERR\_NGROK\_15001](/docs/errors/err_ngrok_15001) | The Webhook Verification secret exceeds the maximum length of `MAX`, got `SIZE`. |
| [ERR\_NGROK\_15002](/docs/errors/err_ngrok_15002) | Your account is on the `PLAN` plan, which requires you to register a Domain or TCP Address through the ngrok Dashboard before starting an Endpoint. Visit [https://dashboard.ngrok.com/domains](https://dashboard.ngrok.com/domains), for HTTP and TLS endpoints, or [https://dashboard.ngrok.com/tcp-addresses](https://dashboard.ngrok.com/tcp-addresses), for TCP endpoints, to register a domain or address. Then use the `--url` flag when starting an HTTP, TLS, or TCP endpoint with your Agent. |
| [ERR\_NGROK\_15003](/docs/errors/err_ngrok_15003) | Upstream protocol is invalid: `APPPROTOCOL` |
| [ERR\_NGROK\_15004](/docs/errors/err_ngrok_15004) | This agent has exceeded its policy rule limit of `LIMIT`. Log into [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) to view your options. |
| [ERR\_NGROK\_15005](/docs/errors/err_ngrok_15005) | The binding `BINDING` is invalid. |
| [ERR\_NGROK\_15006](/docs/errors/err_ngrok_15006) | The binding `BINDING` was specified multiple times, but duplicate bindings are not allowed. |
| [ERR\_NGROK\_15007](/docs/errors/err_ngrok_15007) | The Webhook Verification secret was not specified. |
| [ERR\_NGROK\_15008](/docs/errors/err_ngrok_15008) | Invalid basic auth credential. Username must be at most `MAXLENGTH` characters, got `GOTLENGTH`. |
| [ERR\_NGROK\_15009](/docs/errors/err_ngrok_15009) | Invalid basic auth credentials list. Your plan is limited to `MAXLENGTH` sets of credentials, got `GOTLENGTH`. |
| [ERR\_NGROK\_15010](/docs/errors/err_ngrok_15010) | The binding `BINDING` refers to a k8s operator that does not exist. |
| [ERR\_NGROK\_15011](/docs/errors/err_ngrok_15011) | Invalid basic auth credential. Username `USERNAME` fails to meet requirements of RFC 7617 #2.1: `ERROR` |
| [ERR\_NGROK\_15012](/docs/errors/err_ngrok_15012) | Invalid basic auth credential. The password of user `USERNAME` fails to meet requirements of RFC 7617 #2.1: `ERROR` |
| [ERR\_NGROK\_15013](/docs/errors/err_ngrok_15013) | Your account is requesting a dev domain that does not exist. Visit [https://dashboard.ngrok.com/domains](https://dashboard.ngrok.com/domains) to request a dev domain. |
| [ERR\_NGROK\_15014](/docs/errors/err_ngrok_15014) | The credential `ID` does not have the `SCOPE` scope required to start a tunnel session. |
| [ERR\_NGROK\_16000](/docs/errors/err_ngrok_16000) | The email of the user you are trying to add, `EMAIL`, does not use a domain verified for your account. |
| [ERR\_NGROK\_17000](/docs/errors/err_ngrok_17000) | The MFA device type "`TYPE`" is invalid. |
| [ERR\_NGROK\_17001](/docs/errors/err_ngrok_17001) | The information supplied for MFA verification was invalid. |
| [ERR\_NGROK\_17002](/docs/errors/err_ngrok_17002) | You do not have any recovery codes configured. |
| [ERR\_NGROK\_17003](/docs/errors/err_ngrok_17003) | The information supplied for recovery code verification was invalid. |
| [ERR\_NGROK\_17004](/docs/errors/err_ngrok_17004) | A matching MFA device was not found. |
| [ERR\_NGROK\_17005](/docs/errors/err_ngrok_17005) | MFA Device verification is not supported. |
| [ERR\_NGROK\_17006](/docs/errors/err_ngrok_17006) | A reason is required to reset MFA for a user. |
| [ERR\_NGROK\_18001](/docs/errors/err_ngrok_18001) | The provided cloud endpoint configuration is invalid: url is invalid. |
| [ERR\_NGROK\_18002](/docs/errors/err_ngrok_18002) | The provided cloud endpoint traffic policy configuration is invalid: `MESSAGE` |
| [ERR\_NGROK\_18003](/docs/errors/err_ngrok_18003) | The provided cloud endpoint configuration is invalid: port is invalid or missing and cannot be inferred from scheme |
| [ERR\_NGROK\_18004](/docs/errors/err_ngrok_18004) | The cloud endpoint update failed because no values were provided. Specify at least one value. |
| [ERR\_NGROK\_18005](/docs/errors/err_ngrok_18005) | The cloud endpoint update failed because you are not allowed to change the protocol/URL scheme in-place. |
| [ERR\_NGROK\_18006](/docs/errors/err_ngrok_18006) | This account does not have any domains or addresses reserved that match the provided URL. |
| [ERR\_NGROK\_18008](/docs/errors/err_ngrok_18008) | This account does not have access to Cloud Endpoints. Upgrade or switch to a pay-as-you-go plan for access. |
| [ERR\_NGROK\_18009](/docs/errors/err_ngrok_18009) | This account already has a cloud endpoint on this URL. |
| [ERR\_NGROK\_18010](/docs/errors/err_ngrok_18010) | You have exceeded the maximum number of cloud endpoints allowed for this account. Log into [https://dashboard.ngrok.com/billing/choose-a-plan](https://dashboard.ngrok.com/billing/choose-a-plan) to view your subscription options. |
| [ERR\_NGROK\_18012](/docs/errors/err_ngrok_18012) | The description field cannot be longer than 255 characters. |
| [ERR\_NGROK\_18013](/docs/errors/err_ngrok_18013) | The metadata field cannot be longer than 4096 characters. |
| [ERR\_NGROK\_18014](/docs/errors/err_ngrok_18014) | The provided cloud endpoint has invalid value for field `FIELD`. Reason: |
| [ERR\_NGROK\_18015](/docs/errors/err_ngrok_18015) | The provided cloud endpoint is missing the required field \`\`FIELD`.` |
| [ERR\_NGROK\_18016](/docs/errors/err_ngrok_18016) | The provided cloud endpoint was invalid because pooling was set to enabled when another endpoint exists for this url that has pooling disabled. |
| [ERR\_NGROK\_18017](/docs/errors/err_ngrok_18017) | The provided cloud endpoint was invalid because pooling was set to disabled when another endpoint exists for this url. |
| [ERR\_NGROK\_18018](/docs/errors/err_ngrok_18018) | Supported protocols for kubernetes-bound endpoints are http, tls, and tcp. You provided `PROTO`. |
| [ERR\_NGROK\_18019](/docs/errors/err_ngrok_18019) | This account does not have access to Endpoint pooling. Upgrade or switch to a pay-as-you-go plan for access. |
| [ERR\_NGROK\_18020](/docs/errors/err_ngrok_18020) | The maximum number of endpoints allowed in this pool has been exceeded. Your account is limited to `LIMIT` endpoints per pool. |
| [ERR\_NGROK\_18021](/docs/errors/err_ngrok_18021) | You have exceeded the maximum number of concurrent endpoints allowed for this account. Log into [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing) to review your usage and [https://dashboard.ngrok.com/billing/choose-a-plan](https://dashboard.ngrok.com/billing/choose-a-plan) to view your subscription options. |
| [ERR\_NGROK\_18022](/docs/errors/err_ngrok_18022) | The provided cloud endpoint configuration is invalid: scheme is invalid or not present. |
| [ERR\_NGROK\_18023](/docs/errors/err_ngrok_18023) | Invalid port for URL with scheme `CURRENTSCHEME`, allowed ports are `WANTPORT`. |
| [ERR\_NGROK\_18024](/docs/errors/err_ngrok_18024) | AI Gateway has moved to [https://app.ngrok.ai](https://app.ngrok.ai). This API only allows managing existing legacy gateways. |
| [ERR\_NGROK\_18025](/docs/errors/err_ngrok_18025) | `ID` is not a valid endpoint ID. |
| [ERR\_NGROK\_19000](/docs/errors/err_ngrok_19000) | Internal Server Error. |
| [ERR\_NGROK\_19001](/docs/errors/err_ngrok_19001) | Certificate Signing Requests Failed! Reason: `ERROR` |
| [ERR\_NGROK\_19002](/docs/errors/err_ngrok_19002) | Failed to validate Kubernetes Operator! Reason: `ERROR` |
| [ERR\_NGROK\_19003](/docs/errors/err_ngrok_19003) | Failed to validate endpoint selectors! Reason: `ERROR` |
| [ERR\_NGROK\_20000](/docs/errors/err_ngrok_20000) | An internal error occurred. |
| [ERR\_NGROK\_20001](/docs/errors/err_ngrok_20001) | Operation failed due to a configuration error: `REASON` |
| [ERR\_NGROK\_20002](/docs/errors/err_ngrok_20002) | Failed to create the Upstream Service for BoundEndpoint. |
| [ERR\_NGROK\_20003](/docs/errors/err_ngrok_20003) | Failed to create the Target Service for BoundEndpoint. |
| [ERR\_NGROK\_20004](/docs/errors/err_ngrok_20004) | Failed to establish a connection between the Upstream and Target Services. |
| [ERR\_NGROK\_20005](/docs/errors/err_ngrok_20005) | BoundEndpoint is Denied due to no matching pattern in AllowedURLs |
| [ERR\_NGROK\_20006](/docs/errors/err_ngrok_20006) | Failed to create CSR. |
| [ERR\_NGROK\_21000](/docs/errors/err_ngrok_21000) | Failed to lookup IP `IP`: `ERR`. |
| [ERR\_NGROK\_23000](/docs/errors/err_ngrok_23000) | The vault name "`VAULT`" is invalid. Must only contain the characters "a-zA-Z0-9\_/.". |
| [ERR\_NGROK\_23001](/docs/errors/err_ngrok_23001) | The vault name cannot be empty. |
| [ERR\_NGROK\_23002](/docs/errors/err_ngrok_23002) | Your vault name must be less than `LENGTH` characters. |
| [ERR\_NGROK\_23003](/docs/errors/err_ngrok_23003) | A Vault must be empty before it can be deleted. Remove all secrets from the vault and try again. |
| [ERR\_NGROK\_23004](/docs/errors/err_ngrok_23004) | Vault names must be unique within an account. |
| [ERR\_NGROK\_23005](/docs/errors/err_ngrok_23005) | You've reached the maximum number of vaults (`MAX`) under your current plan. To increase your limit, upgrade your plan at [https://dashboard.ngrok.com/billing](https://dashboard.ngrok.com/billing). |
| [ERR\_NGROK\_24000](/docs/errors/err_ngrok_24000) | The secret name "`SECRET`" is invalid. Must only contain the characters "a-zA-Z0-9\_/.". |
| [ERR\_NGROK\_24001](/docs/errors/err_ngrok_24001) | The secret name cannot be empty. |
| [ERR\_NGROK\_24002](/docs/errors/err_ngrok_24002) | Your secret name must be less than `LENGTH` characters. |
| [ERR\_NGROK\_24003](/docs/errors/err_ngrok_24003) | The secret value cannot be empty. |
| [ERR\_NGROK\_24004](/docs/errors/err_ngrok_24004) | Your secret value must be less than `LENGTH` bytes. |
| [ERR\_NGROK\_24005](/docs/errors/err_ngrok_24005) | Secret names must be unique within a vault. |
| [ERR\_NGROK\_24006](/docs/errors/err_ngrok_24006) | Vault with ID `ID` not found. |
| [ERR\_NGROK\_24007](/docs/errors/err_ngrok_24007) | You've reached the maximum number of secrets (`MAX`) allowed for vault `VID` under your current plan. To increase your limit, please upgrade your plan or contact support. |
| [ERR\_NGROK\_24008](/docs/errors/err_ngrok_24008) | Required parameter 'VaultID' is missing. |
| [ERR\_NGROK\_24009](/docs/errors/err_ngrok_24009) | Vault not found with name: `NAME` |
| [ERR\_NGROK\_25000](/docs/errors/err_ngrok_25000) | Domain controls with redirect\_blocked\_signups\_to\_sso enabled cannot have an empty or null sso account IDs list. |
| [ERR\_NGROK\_26000](/docs/errors/err_ngrok_26000) | CAA records for domain `DOMAIN` found at `FOUNDAT` do not authorize Let's Encrypt to issue certificates: `REASON` |
| [ERR\_NGROK\_26001](/docs/errors/err_ngrok_26001) | CAA records for domain `DOMAIN` found at `FOUNDAT` contain an accounturi parameter restriction (`ACCOUNTURI`). This restriction cannot be validated for managed certificates. |
| [ERR\_NGROK\_26002](/docs/errors/err_ngrok_26002) | CAA records for domain `DOMAIN` found at `FOUNDAT` contain unknown critical property tags `TAGS` which cannot be processed. |
| [ERR\_NGROK\_26004](/docs/errors/err_ngrok_26004) | CAA records for domain `DOMAIN` found at `FOUNDAT` restrict validation methods to `ALLOWEDMETHOD`, but `REQUIREDMETHOD` is required for this domain type. |
| [ERR\_NGROK\_26005](/docs/errors/err_ngrok_26005) | CAA records for domain `DOMAIN` found at `FOUNDAT` contain malformed data: `ERROR` |
| [ERR\_NGROK\_26006](/docs/errors/err_ngrok_26006) | Certificate provisioning failed unexpectedly: `ERR` |
| [ERR\_NGROK\_26007](/docs/errors/err_ngrok_26007) | Load CSR failed unexpectedly: `ERR` |
| [ERR\_NGROK\_26008](/docs/errors/err_ngrok_26008) | Preflight check failed unexpectedly: `ERR` |
| [ERR\_NGROK\_26009](/docs/errors/err_ngrok_26009) | Certificate obtain failed unexpectedly: `ERR` |
| [ERR\_NGROK\_26010](/docs/errors/err_ngrok_26010) | Certificate conversion failed unexpectedly: `ERR` |
| [ERR\_NGROK\_26011](/docs/errors/err_ngrok_26011) | Certificate finalization failed unexpectedly: `ERR` |
| [ERR\_NGROK\_26012](/docs/errors/err_ngrok_26012) | Preflight check failed: `CHECK` |
| [ERR\_NGROK\_26013](/docs/errors/err_ngrok_26013) | Certificate obtain failed: `ERR` |
| [ERR\_NGROK\_26014](/docs/errors/err_ngrok_26014) | CAA check failed: CAA blocked |
| [ERR\_NGROK\_26015](/docs/errors/err_ngrok_26015) | DCV check failed: CNAME not found |
| [ERR\_NGROK\_26016](/docs/errors/err_ngrok_26016) | DCV check failed: CNAME mismatch |
| [ERR\_NGROK\_26017](/docs/errors/err_ngrok_26017) | DCV check failed: NS not found |
| [ERR\_NGROK\_26018](/docs/errors/err_ngrok_26018) | DCV check failed: NS mismatch |
| [ERR\_NGROK\_26019](/docs/errors/err_ngrok_26019) | DNS-01 check failed: DNS-01 challenge CNAME not found |
| [ERR\_NGROK\_26020](/docs/errors/err_ngrok_26020) | DNS-01 check failed: DNS-01 challenge CNAME mismatch |
| [ERR\_NGROK\_26021](/docs/errors/err_ngrok_26021) | HTTP-01 check failed: HTTP-01 unreachable |
| [ERR\_NGROK\_26022](/docs/errors/err_ngrok_26022) | HTTP-01 check failed: HTTP-01 token mismatch |
| [ERR\_NGROK\_26023](/docs/errors/err_ngrok_26023) | Certificate obtain failed: `ERR` |
| [ERR\_NGROK\_26024](/docs/errors/err_ngrok_26024) | Certificate obtain failed: `ERR` |
| [ERR\_NGROK\_26025](/docs/errors/err_ngrok_26025) | Certificate obtain failed: `ERR` |
| [ERR\_NGROK\_26026](/docs/errors/err_ngrok_26026) | CAA check failed: CAA malformed |
| [ERR\_NGROK\_26027](/docs/errors/err_ngrok_26027) | CAA check failed: CAA DNS lookup failed |
| [ERR\_NGROK\_26028](/docs/errors/err_ngrok_26028) | CAA check failed: CAA unknown critical flag |
| [ERR\_NGROK\_26029](/docs/errors/err_ngrok_26029) | CAA check failed: CAA TLD not found |
| [ERR\_NGROK\_26030](/docs/errors/err_ngrok_26030) | Certificate obtain failed: `ERR` |
| [ERR\_NGROK\_26031](/docs/errors/err_ngrok_26031) | Certificate obtain failed: `ERR` |
| [ERR\_NGROK\_26032](/docs/errors/err_ngrok_26032) | Certificate obtain failed: `ERR` |
| [ERR\_NGROK\_26033](/docs/errors/err_ngrok_26033) | Certificate provisioning failed: account is suspended |
| [ERR\_NGROK\_26034](/docs/errors/err_ngrok_26034) | Check if account is suspended failed unexpectedly: `ERR` |
| [ERR\_NGROK\_26035](/docs/errors/err_ngrok_26035) | Certificate obtain failed: `ERR` |
| [ERR\_NGROK\_26036](/docs/errors/err_ngrok_26036) | Certificate obtain failed: `ERR` |
| [ERR\_NGROK\_26037](/docs/errors/err_ngrok_26037) | Certificate obtain failed: `ERR` |
| [ERR\_NGROK\_26038](/docs/errors/err_ngrok_26038) | Certificate obtain failed: `ERR` |
| [ERR\_NGROK\_26039](/docs/errors/err_ngrok_26039) | DCV check failed: no address records at domain apex |
| [ERR\_NGROK\_26040](/docs/errors/err_ngrok_26040) | DCV check failed: domain apex does not resolve to ngrok |
| [ERR\_NGROK\_26041](/docs/errors/err_ngrok_26041) | DCV check failed: authoritative nameserver unreachable |
| [ERR\_NGROK\_27001](/docs/errors/err_ngrok_27001) | This account does not have access to AI Gateway API Keys. |
| [ERR\_NGROK\_27002](/docs/errors/err_ngrok_27002) | The specified endpoint, `ENDPOINT_ID`, was not found. |
| [ERR\_NGROK\_27003](/docs/errors/err_ngrok_27003) | The specified endpoint, `ENDPOINT_ID`, does not have AI Gateway action enabled. |
| [ERR\_NGROK\_27004](/docs/errors/err_ngrok_27004) | The description field cannot be longer than 255 characters. was `REQLEN` |
| [ERR\_NGROK\_27005](/docs/errors/err_ngrok_27005) | The metadata field cannot be longer than 4096 characters. was `REQLEN` |
| [ERR\_NGROK\_27006](/docs/errors/err_ngrok_27006) | The `MISSING` field is required. |
| [ERR\_NGROK\_27007](/docs/errors/err_ngrok_27007) | The provided API key is invalid or does not exist. Verify the key is correct and has not been deleted. Keys begin with ng\_. |
| [ERR\_NGROK\_27008](/docs/errors/err_ngrok_27008) | This API key is scoped to a different gateway. Each key can only be used with the endpoint it was created for. Check the key's endpoint in the dashboard or create a new key for this gateway. |
| [ERR\_NGROK\_27009](/docs/errors/err_ngrok_27009) | Failed to validate API key. Please try again later. |
| [ERR\_NGROK\_27201](/docs/errors/err_ngrok_27201) | Authentication failed: `REASON` |
| [ERR\_NGROK\_27202](/docs/errors/err_ngrok_27202) | No keys available for provider "`PROVIDERID`". |
| [ERR\_NGROK\_27203](/docs/errors/err_ngrok_27203) | Cannot use ngrok-managed key for unknown model "`MODELID`": pricing required for billing. |
| [ERR\_NGROK\_27204](/docs/errors/err_ngrok_27204) | Unsupported API surface "`PATH`". |
| [ERR\_NGROK\_27205](/docs/errors/err_ngrok_27205) | API surface "`SURFACE`" is not implemented. |
| [ERR\_NGROK\_27206](/docs/errors/err_ngrok_27206) | Credit check failed: `REASON` |
| [ERR\_NGROK\_27207](/docs/errors/err_ngrok_27207) | Upstream request timed out. |
| [ERR\_NGROK\_27208](/docs/errors/err_ngrok_27208) | All retries exhausted, last error: `LASTERROR` |
| [ERR\_NGROK\_27210](/docs/errors/err_ngrok_27210) | Upstream provider rejected the request: `REASON` |
| [ERR\_NGROK\_27211](/docs/errors/err_ngrok_27211) | Upstream provider rejected the API key. |
| [ERR\_NGROK\_27212](/docs/errors/err_ngrok_27212) | Upstream provider denied access. |
| [ERR\_NGROK\_27213](/docs/errors/err_ngrok_27213) | Upstream provider returned not found. |
| [ERR\_NGROK\_27214](/docs/errors/err_ngrok_27214) | Upstream provider request timed out. |
| [ERR\_NGROK\_27215](/docs/errors/err_ngrok_27215) | Request payload exceeded upstream provider limits. |
| [ERR\_NGROK\_27216](/docs/errors/err_ngrok_27216) | Upstream provider could not process the request: `REASON` |
| [ERR\_NGROK\_27217](/docs/errors/err_ngrok_27217) | Upstream provider rate limit exceeded. |
| [ERR\_NGROK\_27218](/docs/errors/err_ngrok_27218) | Upstream provider returned an internal server error. |
| [ERR\_NGROK\_27219](/docs/errors/err_ngrok_27219) | Upstream provider returned a bad gateway error. |
| [ERR\_NGROK\_27220](/docs/errors/err_ngrok_27220) | Upstream provider is unavailable. |
| [ERR\_NGROK\_27221](/docs/errors/err_ngrok_27221) | Upstream provider gateway timed out. |
| [ERR\_NGROK\_27222](/docs/errors/err_ngrok_27222) | Upstream provider returned an unexpected status: `REASON` |
| [ERR\_NGROK\_27223](/docs/errors/err_ngrok_27223) | Network error contacting upstream provider: `REASON` |
| [ERR\_NGROK\_27224](/docs/errors/err_ngrok_27224) | Unknown model "`MODELID`".`SUGGESTION` |
| [ERR\_NGROK\_27225](/docs/errors/err_ngrok_27225) | Unknown provider "`PROVIDERID`". |
| [ERR\_NGROK\_27226](/docs/errors/err_ngrok_27226) | Provider "`PROVIDERID`" does not support API surface "`SURFACE`". |
| [ERR\_NGROK\_27227](/docs/errors/err_ngrok_27227) | No backend available: `REASON` |
| [ERR\_NGROK\_27228](/docs/errors/err_ngrok_27228) | Invalid request: `REASON` |
| [ERR\_NGROK\_27229](/docs/errors/err_ngrok_27229) | Invalid model address "`ADDRESS`". |
| [ERR\_NGROK\_27230](/docs/errors/err_ngrok_27230) | "`MODEL`" is not a known model, and "`PROVIDER`" is not a recognized provider. |
| [ERR\_NGROK\_27231](/docs/errors/err_ngrok_27231) | Provider "`PROVIDERID`" is not allowed by the access policy. |
| [ERR\_NGROK\_27232](/docs/errors/err_ngrok_27232) | Model "`MODELID`" is not allowed by the access policy. |
| [ERR\_NGROK\_27233](/docs/errors/err_ngrok_27233) | ngrok has no catalog entry for "`MODELID`" on provider "`PROVIDERID`", so an ngrok-managed key can't serve it. Add your own provider key to use it. |
| [ERR\_NGROK\_27234](/docs/errors/err_ngrok_27234) | Upstream provider returned a non-streaming response (content-type `CONTENTTYPE`) despite a streaming request. |
| [ERR\_NGROK\_27235](/docs/errors/err_ngrok_27235) | Upstream provider failed to respond. |
| [ERR\_NGROK\_27236](/docs/errors/err_ngrok_27236) | Model "`MODELID`" is not priced for managed billing yet for provider "`PROVIDERID`"; add your own provider key to use it. |
| [ERR\_NGROK\_27237](/docs/errors/err_ngrok_27237) | Request rejected: a routing loop was detected. Double check your custom provider URLs do not cause an infinite proxy loop. |
| [ERR\_NGROK\_27238](/docs/errors/err_ngrok_27238) | An ngrok-managed key can't serve this request, because ngrok can't bill `FEATURE` for "`MODELID`" on provider "`PROVIDERID`". Add your own provider key to use it. |
| [ERR\_NGROK\_27239](/docs/errors/err_ngrok_27239) | ngrok can't serve "`MODELID`" on provider "`PROVIDERID`" with an ngrok-managed key right now. Add your own provider key to use it. |
| [ERR\_NGROK\_27240](/docs/errors/err_ngrok_27240) | Your account has no `FILES` for provider "`PROVIDERID`". An ngrok-managed key can only use files your account uploaded. Upload the file first, or add your own provider key. |
| [ERR\_NGROK\_27241](/docs/errors/err_ngrok_27241) | The `HEADER` header is required on Files API requests. Set it to one of: `PROVIDERS`. |
| [ERR\_NGROK\_27242](/docs/errors/err_ngrok_27242) | Provider "`PROVIDERID`" does not support the Files API. Supported providers: `PROVIDERS`. |
| [ERR\_NGROK\_27243](/docs/errors/err_ngrok_27243) | The Files API "`PARAMETER`" parameter must be a whole number from 1 to `MAXIMUM`. Ask for a smaller page, then follow the cursor the response returns to read the rest. |
| [ERR\_NGROK\_27244](/docs/errors/err_ngrok_27244) | Your account has no file "`FILEID`" for provider "`PROVIDERID`". |
| [ERR\_NGROK\_27245](/docs/errors/err_ngrok_27245) | The Files API cannot apply "`PARAMETER`" to a listing served by an ngrok-managed key for provider "`PROVIDERID`". Drop the parameter, or add your own provider key. |
| [ERR\_NGROK\_27246](/docs/errors/err_ngrok_27246) | Your account already holds `USEDBYTES` of the `LIMITBYTES` an ngrok-managed key allows for provider "`PROVIDERID`". Delete files you no longer need, or add your own provider key. |
| [ERR\_NGROK\_27247](/docs/errors/err_ngrok_27247) | A Files API upload for provider "`PROVIDERID`" must be a multipart/form-data request. |
| [ERR\_NGROK\_27248](/docs/errors/err_ngrok_27248) | A Files API upload can be at most `LIMIT`. Send a smaller file, or upload it to your provider account directly. |
| [ERR\_NGROK\_27249](/docs/errors/err_ngrok_27249) | ngrok doesn't offer "`MODELID`" on provider "`PROVIDERID`" with an ngrok-managed key. Add your own provider key to use it. |
| [ERR\_NGROK\_27250](/docs/errors/err_ngrok_27250) | ngrok doesn't store interactions yet, so "store" can't be true. Omit it or set it to false to send a stateless request. |
| [ERR\_NGROK\_27501](/docs/errors/err_ngrok_27501) | The name field cannot be longer than 255 characters. was `REQLEN` |
| [ERR\_NGROK\_27502](/docs/errors/err_ngrok_27502) | The description field cannot be longer than 255 characters. was `REQLEN` |
| [ERR\_NGROK\_27503](/docs/errors/err_ngrok_27503) | The metadata field cannot be longer than 4096 characters. was `REQLEN` |
| [ERR\_NGROK\_27504](/docs/errors/err_ngrok_27504) | This account does not have access to AI Gateway Provider Keys. |
| [ERR\_NGROK\_27505](/docs/errors/err_ngrok_27505) | AI Gateway provider key encryption is not configured for this deployment |
| [ERR\_NGROK\_27506](/docs/errors/err_ngrok_27506) | Cannot create more than `MAXKEYS` provider keys for provider "`PROVIDERID`" on a single managed key. |
| [ERR\_NGROK\_27507](/docs/errors/err_ngrok_27507) | The value field is required and cannot be empty. |
| [ERR\_NGROK\_27508](/docs/errors/err_ngrok_27508) | The provider\_id "`PROVIDERID`" is not a supported AI provider. |
| [ERR\_NGROK\_27509](/docs/errors/err_ngrok_27509) | The specified AI Gateway API Key, `AIGKID`, was not found. |
| [ERR\_NGROK\_27510](/docs/errors/err_ngrok_27510) | The `MISSING` field is required. |
| [ERR\_NGROK\_27511](/docs/errors/err_ngrok_27511) | This provider key cannot be deleted because it is referenced by a router rule. Remove those references first. |
| [ERR\_NGROK\_27601](/docs/errors/err_ngrok_27601) | AI Gateway is currently in pre-release and not yet available to your account. |
| [ERR\_NGROK\_27602](/docs/errors/err_ngrok_27602) | The `MISSING` field is required. |
| [ERR\_NGROK\_27603](/docs/errors/err_ngrok_27603) | The name field cannot be longer than 255 characters. was `REQLEN` |
| [ERR\_NGROK\_27604](/docs/errors/err_ngrok_27604) | The metadata field cannot be longer than 4096 characters. was `REQLEN` |
| [ERR\_NGROK\_27605](/docs/errors/err_ngrok_27605) | Invalid router configuration: `REASON`. |
| [ERR\_NGROK\_27606](/docs/errors/err_ngrok_27606) | `REASON` |
| [ERR\_NGROK\_27607](/docs/errors/err_ngrok_27607) | Resource already exists. |
| [ERR\_NGROK\_27609](/docs/errors/err_ngrok_27609) | Request canceled. |
| [ERR\_NGROK\_27610](/docs/errors/err_ngrok_27610) | Request deadline exceeded. |
| [ERR\_NGROK\_27611](/docs/errors/err_ngrok_27611) | `RESOURCE` not found. |
| [ERR\_NGROK\_27612](/docs/errors/err_ngrok_27612) | Operation not implemented: `OPERATION` |
| [ERR\_NGROK\_27613](/docs/errors/err_ngrok_27613) | Upstream service error. |
| [ERR\_NGROK\_27614](/docs/errors/err_ngrok_27614) | Method not allowed. |
| [ERR\_NGROK\_27615](/docs/errors/err_ngrok_27615) | The resource is still in use and cannot be deleted. |
| [ERR\_NGROK\_27616](/docs/errors/err_ngrok_27616) | A credit purchase is already in progress. Wait for it to finish before starting another. |
| [ERR\_NGROK\_27617](/docs/errors/err_ngrok_27617) | The idempotency key was already used for a different request. Use a new key. |
| [ERR\_NGROK\_27701](/docs/errors/err_ngrok_27701) | The name field cannot be longer than 255 characters. was `REQLEN` |
| [ERR\_NGROK\_27702](/docs/errors/err_ngrok_27702) | The metadata field cannot be longer than 4096 characters. was `REQLEN` |
| [ERR\_NGROK\_27703](/docs/errors/err_ngrok_27703) | The base\_url field cannot be longer than 2048 characters. was `REQLEN` |
| [ERR\_NGROK\_27704](/docs/errors/err_ngrok_27704) | The `MISSING` field is required. |
| [ERR\_NGROK\_27705](/docs/errors/err_ngrok_27705) | The provider\_id "`PROVIDERID`" is reserved by a built-in ngrok provider and cannot be used for a user-defined provider. |
| [ERR\_NGROK\_27706](/docs/errors/err_ngrok_27706) | The provider\_id field cannot be longer than 255 characters. was `REQLEN` |
| [ERR\_NGROK\_27707](/docs/errors/err_ngrok_27707) | The API surface format "`FORMAT`" is not a supported ngrok format. |
| [ERR\_NGROK\_27708](/docs/errors/err_ngrok_27708) | The API surface "`SURFACE`" is not a supported ngrok surface. |
| [ERR\_NGROK\_27709](/docs/errors/err_ngrok_27709) | The model\_id field cannot be longer than 255 characters. was `REQLEN` |
| [ERR\_NGROK\_27710](/docs/errors/err_ngrok_27710) | This provider cannot be deleted because it is referenced by a provider key or an access key configuration. Remove those references first. |
| [ERR\_NGROK\_27711](/docs/errors/err_ngrok_27711) | The model\_id "`MODELID`" is listed more than once for this provider. |
| [ERR\_NGROK\_27712](/docs/errors/err_ngrok_27712) | A provider with provider\_id "`PROVIDERID`" already exists for this account. |
| [ERR\_NGROK\_27713](/docs/errors/err_ngrok_27713) | The provider\_model\_id field cannot be longer than 255 characters. was `REQLEN` |
| [ERR\_NGROK\_27714](/docs/errors/err_ngrok_27714) | An unsupported\_params entry cannot be longer than 255 characters. was `REQLEN` |
| [ERR\_NGROK\_27715](/docs/errors/err_ngrok_27715) | The unsupported\_params entry "`PARAM`" is listed more than once for this model. |
| [ERR\_NGROK\_27716](/docs/errors/err_ngrok_27716) | The unsupported\_params array cannot contain more than 100 entries. was `REQLEN` |
| [ERR\_NGROK\_27717](/docs/errors/err_ngrok_27717) | The unsupported\_params array contains an empty string; every entry must be a non-empty param name. |
| [ERR\_NGROK\_27718](/docs/errors/err_ngrok_27718) | The base\_url host "`HOST`" is not allowed. |
| [ERR\_NGROK\_28000](/docs/errors/err_ngrok_28000) | Pod identity metadata too large: `REASON` |
| [ERR\_NGROK\_28001](/docs/errors/err_ngrok_28001) | Failed to retrieve pod identity metadata: ensure pod has proper annotations and service account configuration |
| [ERR\_NGROK\_29000](/docs/errors/err_ngrok_29000) | Your account is limited to `MAX` personal access tokens. |
| [ERR\_NGROK\_29001](/docs/errors/err_ngrok_29001) | You don't have permission to perform this action. Your credentials are missing the `SCOPE` scope. |
| [ERR\_NGROK\_AI\_GATEWAY\_REQUEST\_BODY\_TOO\_LONG](/docs/errors/err_ngrok_ai_gateway_request_body_too_long) | Request body is too long. Max `LIMIT`. |
| [ERR\_NGROK\_BILLING\_CARD\_MANDATE\_IN\_PROGRESS](/docs/errors/err_ngrok_billing_card_mandate_in_progress) | Your bank is still approving this card for automatic payments. This takes a few minutes. You can complete the purchase once it finishes. |
| [ERR\_NGROK\_BILLING\_CARD\_MANDATE\_REFUSED](/docs/errors/err_ngrok_billing_card_mandate_refused) | Your bank refused to approve this card for automatic payments. Use a different card. |
| [ERR\_NGROK\_IAM\_ACCESS\_TOKEN\_OWNER\_ROLE\_REQUIRED](/docs/errors/err_ngrok_iam_access_token_owner_role_required) | The token owner has no role that grants access. Give the owner a role first. |
| [ERR\_NGROK\_IAM\_SERVICE\_USER\_PERMISSIONS\_USE\_ROLES](/docs/errors/err_ngrok_iam_service_user_permissions_use_roles) | You can't set a service user's permissions directly. Change its roles instead. |
| [ERR\_NGROK\_IAM\_SERVICE\_USER\_ROLE\_CONFLICT](/docs/errors/err_ngrok_iam_service_user_role_conflict) | A service user can hold only one of the roles 'developer' and 'developer-readonly'. |
| [ERR\_NGROK\_IAM\_SERVICE\_USER\_ROLE\_NOT\_ALLOWED](/docs/errors/err_ngrok_iam_service_user_role_not_allowed) | A service user can't hold the role `ROLE`. Allowed roles: developer, developer-readonly, team-manager. |
| [ERR\_NGROK\_SHIP\_APP\_BUILD\_CONFIG\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_app_build_config_not_allowed) | The 'build\_config' field applies only to repository apps. |
| [ERR\_NGROK\_SHIP\_APP\_ENVIRONMENTS\_OR\_PR\_PREVIEWS\_REQUIRED](/docs/errors/err_ngrok_ship_app_environments_or_pr_previews_required) | The request must include at least one environment or 'pr\_previews'. |
| [ERR\_NGROK\_SHIP\_APP\_ENVIRONMENTS\_REQUIRED](/docs/errors/err_ngrok_ship_app_environments_required) | The 'environments' list must include at least one environment. |
| [ERR\_NGROK\_SHIP\_APP\_ENVIRONMENT\_BRANCH\_REQUIRED](/docs/errors/err_ngrok_ship_app_environment_branch_required) | The 'environments\[`INDEX`].branch' field must not be empty. |
| [ERR\_NGROK\_SHIP\_APP\_ENVIRONMENT\_NAME\_DUPLICATED](/docs/errors/err_ngrok_ship_app_environment_name_duplicated) | Environment name `NAME` is used more than once in 'environments'. |
| [ERR\_NGROK\_SHIP\_APP\_ENVIRONMENT\_NAME\_REQUIRED](/docs/errors/err_ngrok_ship_app_environment_name_required) | The 'environments\[`INDEX`].name' field is required. No name derives from branch `BRANCH`. |
| [ERR\_NGROK\_SHIP\_APP\_ENVIRONMENT\_TRACKING\_REF\_REQUIRED](/docs/errors/err_ngrok_ship_app_environment_tracking_ref_required) | Environment `NAME` must have a 'tracking\_ref'. |
| [ERR\_NGROK\_SHIP\_APP\_ENVIRONMENT\_URL\_DUPLICATED](/docs/errors/err_ngrok_ship_app_environment_url_duplicated) | Environment URL `URL` is used more than once in 'environments'. |
| [ERR\_NGROK\_SHIP\_APP\_IMAGE\_REPOSITORY\_REQUIRED](/docs/errors/err_ngrok_ship_app_image_repository_required) | The 'image\_repository' field must not be empty. |
| [ERR\_NGROK\_SHIP\_APP\_NAME\_ALREADY\_EXISTS](/docs/errors/err_ngrok_ship_app_name_already_exists) | An app named "`NAME`" already exists on this account. |
| [ERR\_NGROK\_SHIP\_APP\_NAME\_BAD\_START\_OR\_END](/docs/errors/err_ngrok_ship_app_name_bad_start_or_end) | App name `NAME` must not start or end with `CHAR`. |
| [ERR\_NGROK\_SHIP\_APP\_NAME\_ILLEGAL\_CHARACTER](/docs/errors/err_ngrok_ship_app_name_illegal_character) | App name `NAME` contains the illegal character `CHAR`. Allowed: lowercase letters, digits, '-', and '\_'. |
| [ERR\_NGROK\_SHIP\_APP\_NAME\_NOT\_FOUND](/docs/errors/err_ngrok_ship_app_name_not_found) | No app named `NAME` exists on this account. |
| [ERR\_NGROK\_SHIP\_APP\_NAME\_REQUIRED](/docs/errors/err_ngrok_ship_app_name_required) | App name must not be empty. |
| [ERR\_NGROK\_SHIP\_APP\_NAME\_TOO\_LONG](/docs/errors/err_ngrok_ship_app_name_too_long) | App name is too long. Max 255 bytes, got `LENGTH` bytes. |
| [ERR\_NGROK\_SHIP\_APP\_NOT\_FOUND](/docs/errors/err_ngrok_ship_app_not_found) | No app with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_APP\_PULL\_CREDENTIAL\_NOT\_FOUND](/docs/errors/err_ngrok_ship_app_pull_credential_not_found) | No registry credential with the ID `ID` exists on this account. Check 'pull\_credential\_id'. |
| [ERR\_NGROK\_SHIP\_APP\_PULL\_CREDENTIAL\_REGISTRY\_CONFLICT](/docs/errors/err_ngrok_ship_app_pull_credential_registry_conflict) | Image repository `REPOSITORY` is not on `HOST`, the registry the credential signs in to. |
| [ERR\_NGROK\_SHIP\_APP\_PULL\_CREDENTIAL\_REQUIRED](/docs/errors/err_ngrok_ship_app_pull_credential_required) | A private repository that publishes to ghcr.io needs a 'pull\_credential\_id'. Runners cannot pull the image without one. |
| [ERR\_NGROK\_SHIP\_APP\_REF\_REQUIRED](/docs/errors/err_ngrok_ship_app_ref_required) | A ship ref is 'ship/' followed by the app name. |
| [ERR\_NGROK\_SHIP\_APP\_REPOSITORY\_CONNECTION\_UNAVAILABLE](/docs/errors/err_ngrok_ship_app_repository_connection_unavailable) | The ngrok GitHub app is `STATE` for this repository. Reinstall or reactivate it on GitHub. |
| [ERR\_NGROK\_SHIP\_APP\_REPOSITORY\_NOT\_CONFIGURED](/docs/errors/err_ngrok_ship_app_repository_not_configured) | App `NAME` has no connected repository. Connect a GitHub repository before you add a continuous delivery. |
| [ERR\_NGROK\_SHIP\_APP\_REPOSITORY\_WORKFLOW\_ALREADY\_EXISTS](/docs/errors/err_ngrok_ship_app_repository_workflow_already_exists) | Workflow `PATH` in this repository is already connected to another app. |
| [ERR\_NGROK\_SHIP\_BUILD\_CONFIG\_BUILD\_COMMAND\_TOO\_LONG](/docs/errors/err_ngrok_ship_build_config_build_command_too_long) | The 'build\_config.build\_command' field is too long. Max 4096 bytes, got `LENGTH` bytes. |
| [ERR\_NGROK\_SHIP\_BUILD\_CONFIG\_COMMANDS\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_build_config_commands_not_allowed) | The 'build\_command' and 'run\_command' fields apply only to automatic builds. |
| [ERR\_NGROK\_SHIP\_BUILD\_CONFIG\_DOCKERFILE\_PATH\_FILE\_REQUIRED](/docs/errors/err_ngrok_ship_build_config_dockerfile_path_file_required) | The 'dockerfile\_path' value `VALUE` must name a file. |
| [ERR\_NGROK\_SHIP\_BUILD\_CONFIG\_DOCKERFILE\_PATH\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_build_config_dockerfile_path_not_allowed) | The 'dockerfile\_path' field applies only to Dockerfile builds. |
| [ERR\_NGROK\_SHIP\_BUILD\_CONFIG\_PATH\_BAD\_START\_OR\_END](/docs/errors/err_ngrok_ship_build_config_path_bad_start_or_end) | The `FIELD` value `VALUE` must not start or end with '/'. |
| [ERR\_NGROK\_SHIP\_BUILD\_CONFIG\_PATH\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_build_config_path_not_allowed) | The `FIELD` value `VALUE` leaves the repository. '..' segments are not allowed. |
| [ERR\_NGROK\_SHIP\_BUILD\_CONFIG\_PATH\_REQUIRED](/docs/errors/err_ngrok_ship_build_config_path_required) | The `FIELD` field must not be empty. |
| [ERR\_NGROK\_SHIP\_BUILD\_CONFIG\_PROVIDER\_UNSUPPORTED](/docs/errors/err_ngrok_ship_build_config_provider_unsupported) | Build provider `PROVIDER` is not supported. Allowed: 'dockerfile' and 'automatic'. |
| [ERR\_NGROK\_SHIP\_BUILD\_CONFIG\_RUN\_COMMAND\_TOO\_LONG](/docs/errors/err_ngrok_ship_build_config_run_command_too_long) | The 'build\_config.run\_command' field is too long. Max 4096 bytes, got `LENGTH` bytes. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_ACCOUNT\_CONNECTION\_ALREADY\_EXISTS](/docs/errors/err_ngrok_ship_chatbot_account_connection_already_exists) | This ngrok account is already connected to a Slack workspace. Disconnect it first. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_CHANNEL\_NAME\_REQUIRED](/docs/errors/err_ngrok_ship_chatbot_channel_name_required) | `PROVIDER` returned no name for channel `CHANNEL`. Subscribe from a named channel. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_CHANNEL\_READ\_UNAVAILABLE](/docs/errors/err_ngrok_ship_chatbot_channel_read_unavailable) | We could not read channel `CHANNEL` from `PROVIDER`: `REASON` |
| [ERR\_NGROK\_SHIP\_CHATBOT\_ENTITLEMENT\_DENIED](/docs/errors/err_ngrok_ship_chatbot_entitlement_denied) | Your plan doesn't include the ngrok chat agent. Upgrade to connect a Slack workspace. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_INSTALLATION\_ENABLED\_REQUIRED](/docs/errors/err_ngrok_ship_chatbot_installation_enabled_required) | The chat agent is paused for this workspace. Resume it in the dashboard before you subscribe a channel. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_INSTALLATION\_NOT\_FOUND](/docs/errors/err_ngrok_ship_chatbot_installation_not_found) | No chat agent installation with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_INSTALLER\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_chatbot_installer_not_allowed) | Only a Slack workspace admin or owner can connect ngrok to this workspace. Ask an admin to reconnect the Slack integration, then try again. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_INTEGRATION\_NOT\_CONFIGURED](/docs/errors/err_ngrok_ship_chatbot_integration_not_configured) | This Slack integration is not connected. Reconnect it, then enable the chatbot again. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_INTEGRATION\_PROVIDER\_UNSUPPORTED](/docs/errors/err_ngrok_ship_chatbot_integration_provider_unsupported) | Integration `ID` is not a chat platform integration. Its provider is `PROVIDER`. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_PROVIDER\_CREDENTIAL\_REFUSED](/docs/errors/err_ngrok_ship_chatbot_provider_credential_refused) | `PROVIDER` rejected the integration's credential (`REASON`). Reconnect the `PROVIDER` integration. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_PROVIDER\_UNAVAILABLE](/docs/errors/err_ngrok_ship_chatbot_provider_unavailable) | We could not reach `PROVIDER` to verify the integration: `REASON` |
| [ERR\_NGROK\_SHIP\_CHATBOT\_SUBSCRIPTION\_FILTER\_INVALID](/docs/errors/err_ngrok_ship_chatbot_subscription_filter_invalid) | Invalid subscription filter: `DETAIL`. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_SUBSCRIPTION\_NOT\_FOUND](/docs/errors/err_ngrok_ship_chatbot_subscription_not_found) | Subscription `ID` not found. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_SUBSCRIPTION\_SUBJECT\_UNSUPPORTED](/docs/errors/err_ngrok_ship_chatbot_subscription_subject_unsupported) | `REF` is not something I can subscribe to. Known namespaces: `NAMESPACES`. |
| [ERR\_NGROK\_SHIP\_CHATBOT\_WORKSPACE\_CONNECTION\_ALREADY\_EXISTS](/docs/errors/err_ngrok_ship_chatbot_workspace_connection_already_exists) | This ngrok account has already connected this Slack workspace. |
| [ERR\_NGROK\_SHIP\_CHECK\_LIMIT\_EXCEEDED](/docs/errors/err_ngrok_ship_check_limit_exceeded) | Too many health checks. Max 10, got `COUNT`. |
| [ERR\_NGROK\_SHIP\_CHECK\_NAME\_BAD\_START](/docs/errors/err_ngrok_ship_check_name_bad_start) | Health check name `NAME` must start with a lowercase letter. |
| [ERR\_NGROK\_SHIP\_CHECK\_NAME\_DUPLICATED](/docs/errors/err_ngrok_ship_check_name_duplicated) | Health check name `NAME` is used more than once. |
| [ERR\_NGROK\_SHIP\_CHECK\_NAME\_ILLEGAL\_CHARACTER](/docs/errors/err_ngrok_ship_check_name_illegal_character) | Health check name `NAME` contains the illegal character `CHAR`. Allowed: lowercase letters, digits, '-', and '\_'. |
| [ERR\_NGROK\_SHIP\_CHECK\_NAME\_REQUIRED](/docs/errors/err_ngrok_ship_check_name_required) | The 'checks\[`INDEX`].name' field must not be empty. |
| [ERR\_NGROK\_SHIP\_CHECK\_NAME\_TOO\_LONG](/docs/errors/err_ngrok_ship_check_name_too_long) | The 'checks\[`INDEX`].name' field is too long. Max 63 bytes, got `LENGTH` bytes. |
| [ERR\_NGROK\_SHIP\_CHECK\_PATH\_BAD\_START](/docs/errors/err_ngrok_ship_check_path_bad_start) | Health check `NAME` path `PATH` must start with '/'. |
| [ERR\_NGROK\_SHIP\_CHECK\_PATH\_ILLEGAL\_CHARACTER](/docs/errors/err_ngrok_ship_check_path_illegal_character) | Health check `NAME` path `PATH` must not contain '?' or '#'. |
| [ERR\_NGROK\_SHIP\_CHECK\_PATH\_REQUIRED](/docs/errors/err_ngrok_ship_check_path_required) | Health check `NAME` must have a 'path'. |
| [ERR\_NGROK\_SHIP\_CHECK\_PATH\_TOO\_LONG](/docs/errors/err_ngrok_ship_check_path_too_long) | Health check `NAME` path is too long. Max 255 bytes, got `LENGTH` bytes. |
| [ERR\_NGROK\_SHIP\_CHECK\_PORT\_OUT\_OF\_RANGE](/docs/errors/err_ngrok_ship_check_port_out_of_range) | Health check `NAME` port must be 1 to 65535, or 0 for the default. Got `PORT`. |
| [ERR\_NGROK\_SHIP\_COMPUTE\_INSTANCE\_OFFERING\_ID\_REQUIRED](/docs/errors/err_ngrok_ship_compute_instance_offering_id_required) | The 'offering\_id' field is required. |
| [ERR\_NGROK\_SHIP\_CONTAINER\_IMAGE\_NOT\_FOUND](/docs/errors/err_ngrok_ship_container_image_not_found) | Image `IMAGE` was not found at `HOST`, or the credential cannot see it. |
| [ERR\_NGROK\_SHIP\_CONTAINER\_IMAGE\_PLATFORM\_REQUIRED](/docs/errors/err_ngrok_ship_container_image_platform_required) | Image `IMAGE` lists no runnable platform. |
| [ERR\_NGROK\_SHIP\_CONTAINER\_IMAGE\_PULL\_CREDENTIAL\_REQUIRED](/docs/errors/err_ngrok_ship_container_image_pull_credential_required) | Registry `HOST` requires a credential to read `IMAGE`. |
| [ERR\_NGROK\_SHIP\_CONTAINER\_IMAGE\_PULL\_DENIED](/docs/errors/err_ngrok_ship_container_image_pull_denied) | Registry `HOST` rejected the pull credential for `IMAGE` (HTTP `STATUS`). |
| [ERR\_NGROK\_SHIP\_CONTAINER\_IMAGE\_REFERENCE\_INVALID](/docs/errors/err_ngrok_ship_container_image_reference_invalid) | The image reference `IMAGE` is not valid: `REASON` |
| [ERR\_NGROK\_SHIP\_CONTAINER\_IMAGE\_REFERENCE\_REQUIRED](/docs/errors/err_ngrok_ship_container_image_reference_required) | The 'image\_ref' field must not be empty. |
| [ERR\_NGROK\_SHIP\_CONTAINER\_IMAGE\_REGISTRY\_ADDRESS\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_container_image_registry_address_not_allowed) | Registry `HOST` resolves to a private or reserved address. ngrok cannot pull from it. |
| [ERR\_NGROK\_SHIP\_CONTAINER\_IMAGE\_REGISTRY\_UNAVAILABLE](/docs/errors/err_ngrok_ship_container_image_registry_unavailable) | Registry `HOST` did not answer for `IMAGE`: `REASON` |
| [ERR\_NGROK\_SHIP\_CONTAINER\_IMAGE\_TAG\_NOT\_FOUND](/docs/errors/err_ngrok_ship_container_image_tag_not_found) | Image `REPOSITORY` has no tag or digest `REFERENCE` at `HOST`. |
| [ERR\_NGROK\_SHIP\_CONTINUOUS\_DELIVERY\_NOT\_FOUND](/docs/errors/err_ngrok_ship_continuous_delivery_not_found) | No continuous delivery with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_CONTINUOUS\_DELIVERY\_PREVIEW\_TRACKING\_REF\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_continuous_delivery_preview_tracking_ref_not_allowed) | A pull request preview tracks its pull request's branch. The 'tracking\_ref' field cannot change. |
| [ERR\_NGROK\_SHIP\_CONTINUOUS\_DELIVERY\_TRACKING\_REF\_NOT\_FOUND](/docs/errors/err_ngrok_ship_continuous_delivery_tracking_ref_not_found) | Branch `BRANCH` does not exist in the repository, or the ngrok GitHub app cannot see it. |
| [ERR\_NGROK\_SHIP\_CONTINUOUS\_DELIVERY\_TRACKING\_REF\_REQUIRED](/docs/errors/err_ngrok_ship_continuous_delivery_tracking_ref_required) | The 'tracking\_ref' field must not be empty. |
| [ERR\_NGROK\_SHIP\_CPU\_MILLICORES\_OUT\_OF\_RANGE](/docs/errors/err_ngrok_ship_cpu_millicores_out_of_range) | The 'cpu\_millicores' field must be 0 or more, got `VALUE`. 0 uses the default. |
| [ERR\_NGROK\_SHIP\_DEPLOYMENT\_NOT\_FOUND](/docs/errors/err_ngrok_ship_deployment_not_found) | No deployment with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_DOCKERFILE\_FROM\_REQUIRED](/docs/errors/err_ngrok_ship_dockerfile_from_required) | Dockerfile `PATH` on branch `BRANCH` has no FROM instruction. |
| [ERR\_NGROK\_SHIP\_DOCKERFILE\_NOT\_FOUND](/docs/errors/err_ngrok_ship_dockerfile_not_found) | Dockerfile `PATH` is missing or empty on branch `BRANCH`. |
| [ERR\_NGROK\_SHIP\_DOCKERFILE\_READ\_REFUSED](/docs/errors/err_ngrok_ship_dockerfile_read_refused) | GitHub refused to read Dockerfile `PATH` from branch `BRANCH` (HTTP `STATUS`). Check the ngrok GitHub app's access to the repository. |
| [ERR\_NGROK\_SHIP\_DOCKERFILE\_READ\_UNAVAILABLE](/docs/errors/err_ngrok_ship_dockerfile_read_unavailable) | GitHub failed to return Dockerfile `PATH` from branch `BRANCH` (HTTP `STATUS`). |
| [ERR\_NGROK\_SHIP\_DOMAIN\_APEX\_UNSUPPORTED](/docs/errors/err_ngrok_ship_domain_apex_unsupported) | `PROVIDER` cannot point a root domain at ngrok. It serves no ALIAS, ANAME, or flattened CNAME record. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_AUTOMATION\_NOT\_CONFIGURED](/docs/errors/err_ngrok_ship_domain_automation_not_configured) | Automated DNS setup is not configured in this environment. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_AUTOMATION\_PROVIDER\_UNSUPPORTED](/docs/errors/err_ngrok_ship_domain_automation_provider_unsupported) | ngrok cannot create DNS records at this provider yet. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_CERT\_ID\_REQUIRED](/docs/errors/err_ngrok_ship_domain_cert_id_required) | The 'cert\_id' field must not be empty when 'cert' is 'uploaded'. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_DNS\_RECORDS\_UNSUPPORTED](/docs/errors/err_ngrok_ship_domain_dns_records_unsupported) | This domain needs no DNS records. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_INTEGRATION\_CREDENTIAL\_REFUSED](/docs/errors/err_ngrok_ship_domain_integration_credential_refused) | The `PROVIDER` integration is not connected or its credential was revoked. Reconnect it in the dashboard. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_MANAGED\_CERT\_REQUIRED](/docs/errors/err_ngrok_ship_domain_managed_cert_required) | This domain does not use a managed certificate. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_NAME\_HOST\_REQUIRED](/docs/errors/err_ngrok_ship_domain_name_host_required) | Domain name has no hostname. ngrok reads only the host part of a pasted URL. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_NAME\_REQUIRED](/docs/errors/err_ngrok_ship_domain_name_required) | Domain name must not be empty. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_PROVIDER\_ACCESS\_DENIED](/docs/errors/err_ngrok_ship_domain_provider_access_denied) | `PROVIDER` refused the integration's credential for `ZONE` (HTTP `STATUS`). Check the API key's permissions. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_PROVIDER\_RATE\_LIMITED](/docs/errors/err_ngrok_ship_domain_provider_rate_limited) | `PROVIDER` is rate limiting DNS API calls for `ZONE`. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_PROVIDER\_ZONE\_NOT\_FOUND](/docs/errors/err_ngrok_ship_domain_provider_zone_not_found) | `PROVIDER` does not have `ZONE`, or its API access is turned off for that domain. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_ZONE\_NOT\_FOUND](/docs/errors/err_ngrok_ship_domain_zone_not_found) | We could not find the DNS zone for this domain. |
| [ERR\_NGROK\_SHIP\_DOMAIN\_ZONE\_READ\_UNAVAILABLE](/docs/errors/err_ngrok_ship_domain_zone_read_unavailable) | We could not read `ZONE` at `PROVIDER`: `REASON` |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_TEMPLATE\_NAME\_BAD\_START](/docs/errors/err_ngrok_ship_endpoint_template_name_bad_start) | Endpoint template name `NAME` must start with a lowercase letter. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_TEMPLATE\_NAME\_DUPLICATED](/docs/errors/err_ngrok_ship_endpoint_template_name_duplicated) | Endpoint template name `NAME` is used more than once. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_TEMPLATE\_NAME\_ILLEGAL\_CHARACTER](/docs/errors/err_ngrok_ship_endpoint_template_name_illegal_character) | Endpoint template name `NAME` contains the illegal character `CHAR`. Allowed: lowercase letters, digits, and '\_'. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_TEMPLATE\_NAME\_REQUIRED](/docs/errors/err_ngrok_ship_endpoint_template_name_required) | The 'endpoint\_templates\[`INDEX`].name' field must not be empty. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_TEMPLATE\_NAME\_TOO\_LONG](/docs/errors/err_ngrok_ship_endpoint_template_name_too_long) | The 'endpoint\_templates\[`INDEX`].name' field is too long. Max 63 bytes, got `LENGTH` bytes. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_TEMPLATE\_PRIMARY\_REQUIRED](/docs/errors/err_ngrok_ship_endpoint_template_primary_required) | The 'endpoint\_templates' list must include a template named 'primary'. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_URL\_DUPLICATED](/docs/errors/err_ngrok_ship_endpoint_url_duplicated) | Endpoint URL `URL` is used more than once in 'endpoint\_templates'. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_URL\_HOST\_REQUIRED](/docs/errors/err_ngrok_ship_endpoint_url_host_required) | The `FIELD` value `VALUE` has no hostname. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_URL\_INVALID](/docs/errors/err_ngrok_ship_endpoint_url_invalid) | The `FIELD` value is not a valid URL: `REASON` |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_URL\_PORT\_REQUIRED](/docs/errors/err_ngrok_ship_endpoint_url_port_required) | The `FIELD` value `VALUE` must include a port for the `SCHEME` scheme. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_URL\_PRIVATE\_HOSTNAME\_LABEL\_LIMIT\_EXCEEDED](/docs/errors/err_ngrok_ship_endpoint_url_private_hostname_label_limit_exceeded) | The `FIELD` hostname `HOST` has too many labels. Max `LIMIT` under this private suffix, got `GOT`. Use hyphens instead of dots. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_URL\_PRIVATE\_HOSTNAME\_NAME\_REQUIRED](/docs/errors/err_ngrok_ship_endpoint_url_private_hostname_name_required) | The `FIELD` hostname `HOST` has no name in front of its private suffix. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_URL\_REQUIRED](/docs/errors/err_ngrok_ship_endpoint_url_required) | The `FIELD` field must not be empty. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_URL\_SCHEME\_REQUIRED](/docs/errors/err_ngrok_ship_endpoint_url_scheme_required) | The `FIELD` value `VALUE` has no scheme. Allowed: https\://, tls\://, or tcp\://. |
| [ERR\_NGROK\_SHIP\_ENDPOINT\_URL\_SCHEME\_UNSUPPORTED](/docs/errors/err_ngrok_ship_endpoint_url_scheme_unsupported) | The `FIELD` value `VALUE` uses the unsupported scheme `SCHEME`. Allowed: https\://, tls\://, or tcp\://. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_ARCHIVED\_ENABLE\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_environment_archived_enable_not_allowed) | Environment `ID` is archived. Unarchive it before you enable it. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_CONTINUOUS\_DELIVERY\_NOT\_CONFIGURED](/docs/errors/err_ngrok_ship_environment_continuous_delivery_not_configured) | Environment `ID` has no continuous delivery, so it cannot be rolled back. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_NAME\_ALREADY\_EXISTS](/docs/errors/err_ngrok_ship_environment_name_already_exists) | An environment named "`NAME`" already exists on this app. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_NAME\_BAD\_START\_OR\_END](/docs/errors/err_ngrok_ship_environment_name_bad_start_or_end) | Environment name `NAME` must not start or end with `CHAR`. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_NAME\_ILLEGAL\_CHARACTER](/docs/errors/err_ngrok_ship_environment_name_illegal_character) | Environment name `NAME` contains the illegal character `CHAR`. Allowed: lowercase letters, digits, '-', and '\_'. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_NAME\_REQUIRED](/docs/errors/err_ngrok_ship_environment_name_required) | Environment name must not be empty. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_NAME\_TOO\_LONG](/docs/errors/err_ngrok_ship_environment_name_too_long) | Environment name is too long. Max 255 bytes, got `LENGTH` bytes. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_NOT\_FOUND](/docs/errors/err_ngrok_ship_environment_not_found) | No environment with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_POOL\_IDS\_REQUIRED](/docs/errors/err_ngrok_ship_environment_pool_ids_required) | The 'pool\_ids' list must include at least one pool. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_POOL\_ID\_INVALID](/docs/errors/err_ngrok_ship_environment_pool_id_invalid) | The 'pool\_ids' entry `VALUE` is not a pool ID: `REASON` |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_POOL\_ID\_NOT\_FOUND](/docs/errors/err_ngrok_ship_environment_pool_id_not_found) | No pool with the ID `ID` exists on this account. Check 'pool\_ids'. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_PREVIEW\_NAME\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_environment_preview_name_not_allowed) | Environment `ID` is a pull request preview. Its name is fixed to the pull request number. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_ROLLOUT\_IN\_PROGRESS](/docs/errors/err_ngrok_ship_environment_rollout_in_progress) | Environment `ID` already has a rollout in progress. Wait for it to finish. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_STATE\_CONFLICT](/docs/errors/err_ngrok_ship_environment_state_conflict) | Environment `ID` is `STATE`. Only an enabled environment can be `ACTION`. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_VAR\_KEY\_BAD\_START](/docs/errors/err_ngrok_ship_environment_var_key_bad_start) | Environment variable `KEY` must not start with a digit. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_VAR\_KEY\_ILLEGAL\_CHARACTER](/docs/errors/err_ngrok_ship_environment_var_key_illegal_character) | Environment variable `KEY` contains the illegal character `CHAR`. Allowed: letters, digits, and '\_'. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_VAR\_KEY\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_environment_var_key_not_allowed) | Environment variable `KEY` is reserved. ngrok sets 'PORT' and the 'PORT\_' variables from the endpoint templates. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_VAR\_KEY\_REQUIRED](/docs/errors/err_ngrok_ship_environment_var_key_required) | Environment variable names must not be empty. |
| [ERR\_NGROK\_SHIP\_ENVIRONMENT\_VAR\_VALUE\_EXPRESSION\_INVALID](/docs/errors/err_ngrok_ship_environment_var_value_expression_invalid) | Environment variable `KEY` has an invalid expression: `REASON` |
| [ERR\_NGROK\_SHIP\_GATEWAY\_CONFIG\_INVALID](/docs/errors/err_ngrok_ship_gateway_config_invalid) | The gateway configuration is invalid: `REASON` |
| [ERR\_NGROK\_SHIP\_GATEWAY\_CONFIG\_REQUIRED](/docs/errors/err_ngrok_ship_gateway_config_required) | The `FIELD` field is required. |
| [ERR\_NGROK\_SHIP\_GATEWAY\_CONFIG\_UNSUPPORTED](/docs/errors/err_ngrok_ship_gateway_config_unsupported) | A `SCHEME` endpoint can't use these gateway settings: `SETTINGS`. Remove them, or use an https\:// URL. |
| [ERR\_NGROK\_SHIP\_GITHUB\_AUTHORIZATION\_REQUIRED](/docs/errors/err_ngrok_ship_github_authorization_required) | Your GitHub authorization has expired or was revoked. Reconnect GitHub. |
| [ERR\_NGROK\_SHIP\_GITHUB\_INSTALLATION\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_github_installation_not_allowed) | Your GitHub user cannot see GitHub installation `INSTALLATIONID`. Configure the ngrok GitHub app's access, or reconnect GitHub. |
| [ERR\_NGROK\_SHIP\_GITHUB\_RATE\_LIMITED](/docs/errors/err_ngrok_ship_github_rate_limited) | GitHub is rate limiting requests for repository `REPO` (HTTP `STATUS`). |
| [ERR\_NGROK\_SHIP\_GITHUB\_READ\_UNAVAILABLE](/docs/errors/err_ngrok_ship_github_read_unavailable) | GitHub did not return `RESOURCE`: `REASON` |
| [ERR\_NGROK\_SHIP\_GITHUB\_REPOSITORY\_ACCESS\_REFUSED](/docs/errors/err_ngrok_ship_github_repository_access_refused) | GitHub refused the ngrok GitHub app's request for repository `REPO` (HTTP 403). Check the app's permissions and repository access. |
| [ERR\_NGROK\_SHIP\_GITHUB\_REPOSITORY\_CONFLICT](/docs/errors/err_ngrok_ship_github_repository_conflict) | GitHub reported a conflict for repository `REPO`: `REASON` |
| [ERR\_NGROK\_SHIP\_GITHUB\_REPOSITORY\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_github_repository_not_allowed) | Your GitHub user cannot see repository `REPOID` through installation `INSTALLATIONID`. |
| [ERR\_NGROK\_SHIP\_GITHUB\_REPOSITORY\_NOT\_FOUND](/docs/errors/err_ngrok_ship_github_repository_not_found) | Repository `REPO` was not found on GitHub, or the ngrok GitHub app has no access to it. |
| [ERR\_NGROK\_SHIP\_GITHUB\_REPOSITORY\_SELECTION\_REQUIRED](/docs/errors/err_ngrok_ship_github_repository_selection_required) | The 'installation\_id' and 'repo\_id' fields must not be 0. |
| [ERR\_NGROK\_SHIP\_GITHUB\_UNAVAILABLE](/docs/errors/err_ngrok_ship_github_unavailable) | GitHub did not answer a request for repository `REPO` (HTTP `STATUS`). |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_AUTHORIZATION\_REQUIRED](/docs/errors/err_ngrok_ship_integration_authorization_required) | Integration `ID` has not been authorized at the provider yet. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_AWS\_ROLE\_ARN\_REQUIRED](/docs/errors/err_ngrok_ship_integration_aws_role_arn_required) | The 'aws.role\_arn' field must not be empty. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_CLIENT\_CREDENTIALS\_REQUIRED](/docs/errors/err_ngrok_ship_integration_client_credentials_required) | The 'client\_credentials.client\_id' and 'client\_credentials.client\_secret' fields must not be empty. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_CLIENT\_ID\_REQUIRED](/docs/errors/err_ngrok_ship_integration_client_id_required) | The 'client\_credentials\_reference.client\_id' field must not be empty. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_CREDENTIAL\_FIELD\_UNSUPPORTED](/docs/errors/err_ngrok_ship_integration_credential_field_unsupported) | Provider `PROVIDERID` has no credential field `NAME`. Allowed: `FIELDS`. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_CREDENTIAL\_INPUT\_UNSUPPORTED](/docs/errors/err_ngrok_ship_integration_credential_input_unsupported) | Provider `PROVIDERID` does not take a `INPUT` credential. It takes `EXPECTED`. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_CREDENTIAL\_REFERENCE\_UNSUPPORTED](/docs/errors/err_ngrok_ship_integration_credential_reference_unsupported) | Provider `PROVIDERID` needs `COUNT` credential values (`FIELDS`). A 'static\_token\_reference' holds one. Send them in 'static\_token\_value'. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_CREDENTIAL\_REQUIRED](/docs/errors/err_ngrok_ship_integration_credential_required) | Provider `PROVIDERID` needs a credential. Send `EXPECTED`. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_CREDENTIAL\_VALUE\_DUPLICATED](/docs/errors/err_ngrok_ship_integration_credential_value_duplicated) | Credential value `NAME` is sent more than once. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_CREDENTIAL\_VALUE\_REQUIRED](/docs/errors/err_ngrok_ship_integration_credential_value_required) | Credential value `NAME` must not be empty. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_ENABLED\_REQUIRED](/docs/errors/err_ngrok_ship_integration_enabled_required) | Integration `ID` is disabled. Enable it first. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_MEMBER\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_integration_member_not_allowed) | Integration `ID` belongs to another member of this account. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_NOT\_FOUND](/docs/errors/err_ngrok_ship_integration_not_found) | No integration with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_PROVIDER\_ID\_UNSUPPORTED](/docs/errors/err_ngrok_ship_integration_provider_id_unsupported) | The 'provider\_id' value `PROVIDERID` is not a provider ngrok supports in this environment. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_PROVIDER\_NOT\_FOUND](/docs/errors/err_ngrok_ship_integration_provider_not_found) | No integration provider with the ID `PROVIDERID` exists. |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_REVOCATION\_REFUSED](/docs/errors/err_ngrok_ship_integration_revocation_refused) | `PROVIDER` refused to revoke the authorization (HTTP `STATUS`). |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_REVOCATION\_UNAVAILABLE](/docs/errors/err_ngrok_ship_integration_revocation_unavailable) | `PROVIDER` did not answer the revocation request: `REASON` |
| [ERR\_NGROK\_SHIP\_INTEGRATION\_REVOCATION\_UNSUPPORTED](/docs/errors/err_ngrok_ship_integration_revocation_unsupported) | ngrok cannot revoke a `PROVIDERID` credential at the provider. Revoke it in the provider console, then delete the integration. |
| [ERR\_NGROK\_SHIP\_MEMORY\_MIB\_OUT\_OF\_RANGE](/docs/errors/err_ngrok_ship_memory_mib_out_of_range) | The 'memory\_mib' field must be 0 or more, got `VALUE`. 0 uses the default. |
| [ERR\_NGROK\_SHIP\_POOL\_AWS\_REGION\_UNSUPPORTED](/docs/errors/err_ngrok_ship_pool_aws_region_unsupported) | The 'region' value `REGION` is not an AWS region code like 'us-east-1'. |
| [ERR\_NGROK\_SHIP\_POOL\_CLUSTER\_NAME\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_pool_cluster_name_not_allowed) | The 'cluster\_name' field must be empty for an 'aws\_ecs\_managed' pool. ngrok names the cluster after the pool ID. |
| [ERR\_NGROK\_SHIP\_POOL\_CLUSTER\_NOT\_FOUND](/docs/errors/err_ngrok_ship_pool_cluster_not_found) | The pool's Kubernetes cluster no longer exists at `PROVIDER`. |
| [ERR\_NGROK\_SHIP\_POOL\_COREWEAVE\_NODE\_POOL\_COUNT\_OUT\_OF\_RANGE](/docs/errors/err_ngrok_ship_pool_coreweave_node_pool_count_out_of_range) | The 'node\_pool.count' field must be at least 1, got `COUNT`. |
| [ERR\_NGROK\_SHIP\_POOL\_DETAILS\_FIELD\_REQUIRED](/docs/errors/err_ngrok_ship_pool_details_field_required) | The `FIELD` field must not be empty. |
| [ERR\_NGROK\_SHIP\_POOL\_DETAILS\_LIST\_REQUIRED](/docs/errors/err_ngrok_ship_pool_details_list_required) | The `FIELD` list must have at least one entry. |
| [ERR\_NGROK\_SHIP\_POOL\_DETAILS\_REQUIRED](/docs/errors/err_ngrok_ship_pool_details_required) | A `KIND` pool needs `KIND` details. The request has none, or has details for another kind. |
| [ERR\_NGROK\_SHIP\_POOL\_ECS\_CLUSTER\_NAME\_ILLEGAL\_CHARACTER](/docs/errors/err_ngrok_ship_pool_ecs_cluster_name_illegal_character) | The 'cluster\_name' value `NAME` contains the illegal character `CHAR`. Allowed: letters, digits, '-', and '\_'. |
| [ERR\_NGROK\_SHIP\_POOL\_ECS\_CLUSTER\_NAME\_TOO\_LONG](/docs/errors/err_ngrok_ship_pool_ecs_cluster_name_too_long) | The 'cluster\_name' field is too long. Max 255 bytes, got `LENGTH` bytes. |
| [ERR\_NGROK\_SHIP\_POOL\_EXECUTION\_ROLE\_ARN\_INVALID](/docs/errors/err_ngrok_ship_pool_execution_role_arn_invalid) | The 'execution\_role\_arn' value is not an IAM role ARN: `REASON` |
| [ERR\_NGROK\_SHIP\_POOL\_EXECUTION\_ROLE\_NAME\_BAD\_START](/docs/errors/err_ngrok_ship_pool_execution_role_name_bad_start) | The 'execution\_role\_arn' role name `NAME` must start with 'ngrok-ship-'. The recommended permissions policy grants iam:PassRole only on that prefix. |
| [ERR\_NGROK\_SHIP\_POOL\_INTEGRATION\_AUTHORIZATION\_REQUIRED](/docs/errors/err_ngrok_ship_pool_integration_authorization_required) | Integration `ID` is not authorized yet. Finish its setup before you create a pool. |
| [ERR\_NGROK\_SHIP\_POOL\_INTEGRATION\_CREDENTIAL\_REFUSED](/docs/errors/err_ngrok_ship_pool_integration_credential_refused) | `PROVIDER` did not accept the integration's credential. Reconnect the integration. |
| [ERR\_NGROK\_SHIP\_POOL\_INTEGRATION\_ENABLED\_REQUIRED](/docs/errors/err_ngrok_ship_pool_integration_enabled_required) | Integration `ID` is disabled. Enable it before you create a pool. |
| [ERR\_NGROK\_SHIP\_POOL\_INTEGRATION\_ID\_REQUIRED](/docs/errors/err_ngrok_ship_pool_integration_id_required) | The 'integration\_id' field must not be empty. A `KIND` pool is provisioned through an integration. |
| [ERR\_NGROK\_SHIP\_POOL\_INTEGRATION\_PROVIDER\_CONFLICT](/docs/errors/err_ngrok_ship_pool_integration_provider_conflict) | Integration `ID` is for `PROVIDER`. A `KIND` pool needs a `WANTED` integration. |
| [ERR\_NGROK\_SHIP\_POOL\_INTEGRATION\_UNSUPPORTED](/docs/errors/err_ngrok_ship_pool_integration_unsupported) | Pool kind `KIND` does not take an 'integration\_id'. |
| [ERR\_NGROK\_SHIP\_POOL\_JOIN\_KEY\_ALREADY\_EXISTS](/docs/errors/err_ngrok_ship_pool_join_key_already_exists) | A pool with this join key already exists on this account. |
| [ERR\_NGROK\_SHIP\_POOL\_JOIN\_KEY\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_pool_join_key_not_allowed) | The 'join\_key' field must not start with 'cp\_'. That prefix is reserved for pool IDs. |
| [ERR\_NGROK\_SHIP\_POOL\_KIND\_NOT\_CONFIGURED](/docs/errors/err_ngrok_ship_pool_kind_not_configured) | Pool kind `KIND` is not available in this environment. |
| [ERR\_NGROK\_SHIP\_POOL\_KIND\_UNSUPPORTED](/docs/errors/err_ngrok_ship_pool_kind_unsupported) | Pool kind `KIND` is not supported. |
| [ERR\_NGROK\_SHIP\_POOL\_LAMBDA\_SSH\_KEY\_CREATE\_UNAVAILABLE](/docs/errors/err_ngrok_ship_pool_lambda_ssh_key_create_unavailable) | Lambda Cloud did not answer the request to create the SSH key: `REASON` |
| [ERR\_NGROK\_SHIP\_POOL\_LAMBDA\_SSH\_KEY\_NAME\_REQUIRED](/docs/errors/err_ngrok_ship_pool_lambda_ssh_key_name_required) | SSH key name must not be empty. |
| [ERR\_NGROK\_SHIP\_POOL\_LAMBDA\_SSH\_KEY\_REFUSED](/docs/errors/err_ngrok_ship_pool_lambda_ssh_key_refused) | Lambda Cloud refused the SSH key (HTTP `STATUS`): `REASON` |
| [ERR\_NGROK\_SHIP\_POOL\_NODE\_POOL\_COUNT\_OUT\_OF\_RANGE](/docs/errors/err_ngrok_ship_pool_node_pool_count_out_of_range) | The 'node\_pools\[`INDEX`].count' field must be 1 to 10, got `COUNT`. |
| [ERR\_NGROK\_SHIP\_POOL\_NODE\_POOL\_FIELD\_REQUIRED](/docs/errors/err_ngrok_ship_pool_node_pool_field_required) | The 'node\_pools\[`INDEX`].`FIELD` field must not be empty. |
| [ERR\_NGROK\_SHIP\_POOL\_NODE\_POOL\_OS\_ID\_ILLEGAL\_CHARACTER](/docs/errors/err_ngrok_ship_pool_node_pool_os_id_illegal_character) | The 'node\_pools\[`INDEX`].os\_id' value `VALUE` must be a whole number. |
| [ERR\_NGROK\_SHIP\_POOL\_NODE\_POOL\_ZONE\_CONFLICT](/docs/errors/err_ngrok_ship_pool_node_pool_zone_conflict) | The 'node\_pools\[`INDEX`].zone' value `ZONE` is not in region `REGION`. |
| [ERR\_NGROK\_SHIP\_POOL\_NOT\_FOUND](/docs/errors/err_ngrok_ship_pool_not_found) | No compute pool with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_POOL\_PROVIDER\_READ\_UNAVAILABLE](/docs/errors/err_ngrok_ship_pool_provider_read_unavailable) | `PROVIDER` did not answer the request to `OPERATION`: `REASON` |
| [ERR\_NGROK\_SHIP\_POOL\_RUNPOD\_COMPUTE\_TYPE\_UNSUPPORTED](/docs/errors/err_ngrok_ship_pool_runpod_compute_type_unsupported) | The 'compute\_type' value `VALUE` is not supported. Allowed: 'GPU' or 'CPU'. |
| [ERR\_NGROK\_SHIP\_POOL\_RUNPOD\_CPU\_FLAVOR\_NOT\_FOUND](/docs/errors/err_ngrok_ship_pool_runpod_cpu_flavor_not_found) | RunPod has no CPU flavor with the ID `ID`. |
| [ERR\_NGROK\_SHIP\_POOL\_RUNPOD\_DATA\_CENTER\_NOT\_FOUND](/docs/errors/err_ngrok_ship_pool_runpod_data_center_not_found) | RunPod has no data center with the ID `ID`. |
| [ERR\_NGROK\_SHIP\_POOL\_RUNPOD\_GPU\_TYPE\_NOT\_FOUND](/docs/errors/err_ngrok_ship_pool_runpod_gpu_type_not_found) | RunPod has no GPU type with the ID `ID`. |
| [ERR\_NGROK\_SHIP\_POOL\_SCALEWAY\_REGION\_UNSUPPORTED](/docs/errors/err_ngrok_ship_pool_scaleway_region_unsupported) | The 'region' value `REGION` is not a Scaleway region. Allowed: `REGIONS`. |
| [ERR\_NGROK\_SHIP\_POOL\_SCALEWAY\_ZONE\_UNSUPPORTED](/docs/errors/err_ngrok_ship_pool_scaleway_zone_unsupported) | The 'zone' value `ZONE` is not a Scaleway instance zone. Allowed: `ZONES`. |
| [ERR\_NGROK\_SHIP\_PORT\_OUT\_OF\_RANGE](/docs/errors/err_ngrok_ship_port_out_of_range) | The 'port' field must be 1 to 65535, got `PORT`. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_APP\_CONFLICT](/docs/errors/err_ngrok_ship_publish_target_app_conflict) | Publish target `ID` is used by `COUNT` apps: `NAMES`. Point them at another target first. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_BUILTIN\_DELETE\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_publish_target_builtin_delete_not_allowed) | The built-in publish target cannot be deleted. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_DOCKER\_HUB\_LOGIN\_REFUSED](/docs/errors/err_ngrok_ship_publish_target_docker_hub_login_refused) | Docker Hub rejected the push credential of publish target `ID` (HTTP `STATUS`). |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_DOCKER\_HUB\_REPOSITORY\_REFUSED](/docs/errors/err_ngrok_ship_publish_target_docker_hub_repository_refused) | Docker Hub refused to create repository `REPOSITORY` (HTTP `STATUS`). Check that the push credential can write to namespace `NAMESPACE`. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_DOCKER\_HUB\_UNAVAILABLE](/docs/errors/err_ngrok_ship_publish_target_docker_hub_unavailable) | Docker Hub did not answer while ngrok prepared repository `REPOSITORY`: `REASON` |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_HOST\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_publish_target_host_not_allowed) | The 'host' field must be empty for a builtin publish target. ngrok manages its host. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_HOST\_UNSUPPORTED](/docs/errors/err_ngrok_ship_publish_target_host_unsupported) | A `KIND` publish target always publishes to `FIXEDHOST`. The 'host' value `HOST` is not allowed. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_KIND\_UNSUPPORTED](/docs/errors/err_ngrok_ship_publish_target_kind_unsupported) | The 'kind' value `KIND` is not supported. Allowed: 'builtin', 'ghcr', 'dockerhub', and 'custom'. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_NOT\_FOUND](/docs/errors/err_ngrok_ship_publish_target_not_found) | No publish target with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_PUSH\_CREDENTIAL\_NOT\_FOUND](/docs/errors/err_ngrok_ship_publish_target_push_credential_not_found) | No registry credential with the ID `ID` exists on this account. Check 'push\_credential\_id'. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_PUSH\_CREDENTIAL\_REQUIRED](/docs/errors/err_ngrok_ship_publish_target_push_credential_required) | A `KIND` publish target needs a 'push\_credential\_id'. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_REPOSITORY\_PREFIX\_BAD\_START](/docs/errors/err_ngrok_ship_publish_target_repository_prefix_bad_start) | Docker Hub namespace `PREFIX` must start with a lowercase letter or digit. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_REPOSITORY\_PREFIX\_ILLEGAL\_CHARACTER](/docs/errors/err_ngrok_ship_publish_target_repository_prefix_illegal_character) | Docker Hub namespace `PREFIX` contains the illegal character `CHAR`. Allowed: lowercase letters, digits, '-', and '\_'. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_REPOSITORY\_PREFIX\_LENGTH\_OUT\_OF\_RANGE](/docs/errors/err_ngrok_ship_publish_target_repository_prefix_length_out_of_range) | Docker Hub namespace must be 2 to 255 bytes, got `LENGTH` bytes. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_REPOSITORY\_PREFIX\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_publish_target_repository_prefix_not_allowed) | The 'repository\_prefix' field must be empty for a `KIND` publish target. ngrok computes the repository name. |
| [ERR\_NGROK\_SHIP\_PUBLISH\_TARGET\_REPOSITORY\_PREFIX\_REQUIRED](/docs/errors/err_ngrok_ship_publish_target_repository_prefix_required) | The 'repository\_prefix' field must not be empty for a `KIND` publish target. |
| [ERR\_NGROK\_SHIP\_PULL\_REQUEST\_TEMPLATE\_NOT\_FOUND](/docs/errors/err_ngrok_ship_pull_request_template_not_found) | No pull request template with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_REGISTRY\_CREDENTIAL\_ALREADY\_EXISTS](/docs/errors/err_ngrok_ship_registry_credential_already_exists) | A credential for `USERNAME` at `HOST` already exists on this account: `ID`. Update it to rotate the password. |
| [ERR\_NGROK\_SHIP\_REGISTRY\_CREDENTIAL\_APP\_CONFLICT](/docs/errors/err_ngrok_ship_registry_credential_app_conflict) | Credential `ID` is the pull credential of `COUNT` apps: `NAMES`. Point them at another credential first. |
| [ERR\_NGROK\_SHIP\_REGISTRY\_CREDENTIAL\_NOT\_FOUND](/docs/errors/err_ngrok_ship_registry_credential_not_found) | No registry credential with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_REGISTRY\_CREDENTIAL\_PASSWORD\_REQUIRED](/docs/errors/err_ngrok_ship_registry_credential_password_required) | The 'password' field must not be empty. |
| [ERR\_NGROK\_SHIP\_REGISTRY\_CREDENTIAL\_PUBLISH\_TARGET\_CONFLICT](/docs/errors/err_ngrok_ship_registry_credential_publish_target_conflict) | Credential `ID` is the push credential of `COUNT` publish targets. Point them at another credential first. |
| [ERR\_NGROK\_SHIP\_REGISTRY\_CREDENTIAL\_REFUSED](/docs/errors/err_ngrok_ship_registry_credential_refused) | Registry `HOST` rejected the credential for user `USERNAME`. |
| [ERR\_NGROK\_SHIP\_REGISTRY\_CREDENTIAL\_USERNAME\_REQUIRED](/docs/errors/err_ngrok_ship_registry_credential_username_required) | The 'username' field must not be empty. |
| [ERR\_NGROK\_SHIP\_REGISTRY\_HOST\_ILLEGAL\_CHARACTER](/docs/errors/err_ngrok_ship_registry_host_illegal_character) | The 'host' value `HOST` contains the illegal character `CHAR`. Use a hostname with an optional port, and no scheme or path. |
| [ERR\_NGROK\_SHIP\_REGISTRY\_HOST\_INVALID](/docs/errors/err_ngrok_ship_registry_host_invalid) | The 'host' value `HOST` is not a registry host: `REASON` |
| [ERR\_NGROK\_SHIP\_REGISTRY\_HOST\_REQUIRED](/docs/errors/err_ngrok_ship_registry_host_required) | The 'host' field must not be empty. |
| [ERR\_NGROK\_SHIP\_RELEASE\_FEED\_CURSOR\_INVALID](/docs/errors/err_ngrok_ship_release_feed_cursor_invalid) | The 'cursor' value is not a cursor this feed returned: `REASON` |
| [ERR\_NGROK\_SHIP\_RELEASE\_NOT\_FOUND](/docs/errors/err_ngrok_ship_release_not_found) | No release with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_REPLICA\_COUNT\_OUT\_OF\_RANGE](/docs/errors/err_ngrok_ship_replica_count_out_of_range) | The 'replica\_count' field must be at least 1, got `COUNT`. |
| [ERR\_NGROK\_SHIP\_REPLICA\_ID\_REQUIRED](/docs/errors/err_ngrok_ship_replica_id_required) | The 'replica\_id' field is required. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_AWS\_ACCESS\_DENIED](/docs/errors/err_ngrok_ship_replica_logs_aws_access_denied) | The AWS integration role is not permitted to read replica logs. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_AWS\_UNAVAILABLE](/docs/errors/err_ngrok_ship_replica_logs_aws_unavailable) | AWS did not answer the replica log read: `REASON` |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_CLOUDWATCH\_LOG\_GROUP\_UNAVAILABLE](/docs/errors/err_ngrok_ship_replica_logs_cloudwatch_log_group_unavailable) | The replica's CloudWatch log group is unavailable. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_CURSOR\_INVALID](/docs/errors/err_ngrok_ship_replica_logs_cursor_invalid) | `REASON` |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_CURSOR\_REQUIRED](/docs/errors/err_ngrok_ship_replica_logs_cursor_required) | The 'cursor' field must not be empty when it is the selected position. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_ECS\_DEPLOYMENT\_UNAVAILABLE](/docs/errors/err_ngrok_ship_replica_logs_ecs_deployment_unavailable) | The replica's current ECS deployment is not available yet. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_INTEGRATION\_CREDENTIAL\_REFUSED](/docs/errors/err_ngrok_ship_replica_logs_integration_credential_refused) | `PROVIDER` did not accept the integration's credential, so replica logs cannot be read. Reconnect the integration. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_KUBERNETES\_POD\_UNAVAILABLE](/docs/errors/err_ngrok_ship_replica_logs_kubernetes_pod_unavailable) | The replica's current Kubernetes Pod is not available yet. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_KUBERNETES\_RBAC\_DENIED](/docs/errors/err_ngrok_ship_replica_logs_kubernetes_rbac_denied) | Kubernetes RBAC does not permit reading replica Pod logs. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_KUBERNETES\_UNAVAILABLE](/docs/errors/err_ngrok_ship_replica_logs_kubernetes_unavailable) | The replica's Kubernetes cluster did not answer the log read: `REASON` |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_LIMIT\_OUT\_OF\_RANGE](/docs/errors/err_ngrok_ship_replica_logs_limit_out_of_range) | The 'limit' field must be 1 to `MAX`, got `LIMIT`. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_PLACEMENT\_REQUIRED](/docs/errors/err_ngrok_ship_replica_logs_placement_required) | The replica has not been placed on a compute pool yet, so it has no logs. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_PREVIOUS\_CONTAINER\_NOT\_FOUND](/docs/errors/err_ngrok_ship_replica_logs_previous_container_not_found) | The replica has no terminated container to read logs from. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_REMOTE\_KUBERNETES\_UNSUPPORTED](/docs/errors/err_ngrok_ship_replica_logs_remote_kubernetes_unsupported) | The runner does not provide access to remote Kubernetes logs. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_REPLICA\_GONE](/docs/errors/err_ngrok_ship_replica_logs_replica_gone) | The replica's current `RESOURCE` no longer exists. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_RUNNER\_ACCESS\_UNAVAILABLE](/docs/errors/err_ngrok_ship_replica_logs_runner_access_unavailable) | The replica's runner has not reported its Kubernetes access as ready. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_RUNPOD\_ACCESS\_DENIED](/docs/errors/err_ngrok_ship_replica_logs_runpod_access_denied) | The RunPod integration is not permitted to read replica logs. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_RUNPOD\_RATE\_LIMITED](/docs/errors/err_ngrok_ship_replica_logs_runpod_rate_limited) | RunPod is temporarily rate limiting replica log reads. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_RUNPOD\_RESOURCE\_CONFLICT](/docs/errors/err_ngrok_ship_replica_logs_runpod_resource_conflict) | More than one current RunPod resource matches this replica. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_RUNPOD\_UNAVAILABLE](/docs/errors/err_ngrok_ship_replica_logs_runpod_unavailable) | RunPod did not answer the replica log read: `REASON` |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_TAIL\_LINES\_LIMIT\_EXCEEDED](/docs/errors/err_ngrok_ship_replica_logs_tail_lines_limit_exceeded) | The 'tail\_lines' value `TAILLINES` must not exceed the 'limit' value `LIMIT`. |
| [ERR\_NGROK\_SHIP\_REPLICA\_LOGS\_TAIL\_LINES\_OUT\_OF\_RANGE](/docs/errors/err_ngrok_ship_replica_logs_tail_lines_out_of_range) | The 'tail\_lines' field must be 0 to `MAX`, got `TAILLINES`. |
| [ERR\_NGROK\_SHIP\_REPLICA\_NOT\_FOUND](/docs/errors/err_ngrok_ship_replica_not_found) | No replica with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_ROLLBACK\_DEPLOYMENT\_ID\_REQUIRED](/docs/errors/err_ngrok_ship_rollback_deployment_id_required) | The 'deployment\_id' field must not be empty. |
| [ERR\_NGROK\_SHIP\_ROLLBACK\_DEPLOYMENT\_NOT\_FOUND](/docs/errors/err_ngrok_ship_rollback_deployment_not_found) | No deployment with the ID `ID` exists in this environment. |
| [ERR\_NGROK\_SHIP\_ROLLBACK\_RELEASE\_NOT\_FOUND](/docs/errors/err_ngrok_ship_rollback_release_not_found) | Deployment `ID` has no release to roll back to. |
| [ERR\_NGROK\_SHIP\_ROLLOUT\_NOT\_FOUND](/docs/errors/err_ngrok_ship_rollout_not_found) | No rollout with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_RUNNER\_NOT\_FOUND](/docs/errors/err_ngrok_ship_runner_not_found) | No runner with the ID `ID` exists on this account. |
| [ERR\_NGROK\_SHIP\_SCHEDULING\_POLICY\_INVALID](/docs/errors/err_ngrok_ship_scheduling_policy_invalid) | The 'scheduling\_policy' expression fails to compile: `REASON` |
| [ERR\_NGROK\_SHIP\_START\_COMMAND\_NOT\_ALLOWED](/docs/errors/err_ngrok_ship_start_command_not_allowed) | The 'start\_command' field is not supported for repository apps. Set the run command in the app's build settings. |
| [ERR\_NGROK\_TRAFFIC\_INSPECT\_CONNECTION\_NOT\_FOUND](/docs/errors/err_ngrok_traffic_inspect_connection_not_found) | This connection was not found. Traffic Inspector keeps connections only for your plan's retention period. |
# FAQ
Source: https://ngrok.com/docs/faq/index
Frequently asked questions about ngrok including status page, payment methods, security, and platform features.
## Does ngrok have an official status page?
Yes, the official ngrok status page is [status.ngrok.com](https://status.ngrok.com).
## Why am I required to add a payment method to use TCP endpoints on the free tier? Will I be charged?
In an effort to combat abuse on the platform, a valid payment method must be [added to your account](https://dashboard.ngrok.com/settings#id-verification) before you can use TCP endpoints on the free tier.
This card will not be charged.
If you remove this card from your account, you will lose access to TCP endpoints until you add another payment method.
Valid payment methods include credit or debit cards.
Prepaid cards may not be used to enable TCP endpoints.
## Is ngrok a virus?
**No, ngrok is not a virus.**
ngrok is beloved for its ease of use and powerful capability.
Unfortunately, those same attributes also make it an attractive target for bad actors trying to phish credentials or create back doors into private networks.
ngrok proactively monitors and bans any accounts identified that are involved with these attacks, and also works with 3rd parties that report malware and abuse via [abuse@ngrok.com](mailto:abuse@ngrok.com) and the [abuse APIs](/docs/api-reference/abusereports/create).
Because ngrok is sometimes used by bad actors for attacks, it is occasionally flagged by some antivirus companies as malware or a potentially unwanted application (PAU).
ngrok actively monitors and reaches out to these companies and attempts to obtain the correct classification in their system and be added to the allow lists.
If you receive a notice from your antivirus software when installing ngrok software, be sure to verify the following:
* Official binaries can be downloaded from the [ngrok Downloads](https://ngrok.com/download) page, and the binaries themselves are hosted at `bin.equinox.io`.
If you installed ngrok from another source, you should be careful.
* There are no open source versions of the ngrok Agent and the source code is not available.
If you have downloaded anything claiming to be ngrok agent source code or built the agent from source, it is most likely malicious.
* All binaries are signed using ngrok certificates.
You can verify the integrity of the application by checking that the binary is signed by an ngrok LLC or ngrok, Inc. authority.
See [these instructions from Microsoft](https://support.microsoft.com/en-us/office/view-digital-signature-and-certificate-details-76ba00cb-1e58-42aa-8717-0caee76bb3cf) for verifying the digital signatures in Windows binaries.
### Does ngrok own `bin.equinox.io`?
Equinox is 100% owned by ngrok (if you visit equinox.io you'll see it redirect to [https://ngrok.com/downloads](https://ngrok.com/downloads)).
ngrok has exclusive access to its source code and its operational infrastructure.
No other software is distributed via equinox.
### How do I verify the ngrok binary is signed?
You can get a binary hash for every ngrok executable distributed (both current and historical) from [https://dl.equinox.io/ngrok/ngrok-v3/stable/archive](https://dl.equinox.io/ngrok/ngrok-v3/stable/archive).
All of those SHAs are correct.
### How does ngrok secure the distribution of binaries?
When ngrok releases new versions of the ngrok agent via equinox, those releases are also signed in multiple ways:
* Each MacOS and Windows release is signed with code-signing certificates that the operating system verifies.
You can verify that those certificates state that ngrok is the publisher.
* The released executables are also signed with a private key that only the release pipeline has access to that are used for ngrok's optional self-update mechanism.
If you ask ngrok to update to a new version (via `ngrok update`) it cryptographically verifies the new version was signed with a trusted CA that is packaged into its executable.
* Uploading new releases to equinox is done in the same CI/CD pipeline that also has isolated access to the authentication keys which are used to upload those executables to the equinox service.
Here is an example verification flow for macOS using the 3.8.0 binary:
```bash theme={null}
❯ codesign -d -vvv ~/Downloads/ngrok
Executable=/Users/username/Downloads/binaries/ngrok
Identifier=darwin_amd64
Format=Mach-O thin (x86_64)
CodeDirectory v=20500 size=209752 flags=0x10000(runtime) hashes=6549+2 location=embedded
Hash type=sha256 size=32
CandidateCDHash sha256=9babe84803ac6c05874966cf0934c116b00b6b97
CandidateCDHashFull sha256=9babe84803ac6c05874966cf0934c116b00b6b97b1daa6ceb6362b8f2e9c63a2
Hash choices=sha256
CMSDigest=9babe84803ac6c05874966cf0934c116b00b6b97b1daa6ceb6362b8f2e9c63a2
CMSDigestType=2
CDHash=9babe84803ac6c05874966cf0934c116b00b6b97
Signature size=8963
Authority=Developer ID Application: ngrok LLC (TEX8MHRDQ9)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=Mar 14, 2024 at 3:18:31 PM
Info.plist=not bound
TeamIdentifier=TEX8MHRDQ9
Runtime Version=11.0.0
Sealed Resources=none
Internal requirements count=1 size=172
```
Most antivirus tools have an option to report false positive classifications for their software.
You can usually find that link in the software itself or on their support site.
[VirusTotal has a large list](https://docs.virustotal.com/docs/false-positive-contacts) of contacts for reporting false positives.
Reporting ngrok is greatly appreciated—this helps ensure ngrok has the correct classification in their systems.
## Does ngrok have built-in protections, rate-limits, or safeguards that help prevent unexpected traffic?
Yes.
All ngrok customer's Endpoints and other resources are protected by our proprietary firewall. In addition, there are [additional measures](/docs/gateway/domains/ddos-protection#additional-measures) that can be taken to
help protect your Endpoints against bad-actors.
## Can I choose a different port to receive traffic on my ngrok domains?
No.
ngrok accepts traffic on port 80 for HTTP endpoints, 443 for HTTPS endpoints and port 443 as well for TLS endpoints.
This behavior is not configurable.
TCP endpoints use the port of the TCP address that was assigned when you acquired the TCP address.
[This port is assigned and not configurable](/docs/gateway/domains/tcp-addresses/#address-assignment).
## Will the ngrok Agent work if my network changes?
Yes.
The ngrok agent is robust to all network changes.
If you switch Wi-Fi networks or your modem restarts and you have a dynamic IP that changes, the ngrok agent will automatically detect this condition and re-establish connectivity with the ngrok cloud service.
You don't need to take any manual action to restart or reconfigure the agent.
## What information is stored about my use of ngrok?
Please see the [Terms of Service](https://ngrok.com/tos) and [Data Processing Agreement](https://ngrok.com/dpa) for more information.
## Does ngrok support CORS?
Yes, applications exposed via ngrok's HTTP endpoints will work with CORS.
Your application must serve the appropriate CORS headers, or you may use ngrok's [response headers module](/docs/gateway/traffic-policy/actions/add-headers/) to add the appropriate CORS headers.
Setting the correct CORS headers is non-trivial, but for very simple examples you may try:
```
ngrok http 80 --response-header-add "Access-Control-Allow-Origin: *"
```
If you use any of ngrok's authentication modules, CORS preflight options requests are blocked by default.
You may override this behavior using [Traffic Policy](/docs/gateway/traffic-policy/) expressions to skip auth enforcement if the request is a CORS preflight request.
Basic Auth (`--basic-auth`) does not yet support configuring options passthrough.
## What's the status of ngrok v1?
The original open source ngrok agent 1.x is [available on GitHub](https://github.com/inconshreveable/ngrok) but is no longer developed, supported or maintained.
The latest ngrok agent is available on the [ngrok downloads page](https://download.ngrok.com).
## How do you pronounce ngrok?
*en-grok*
## How long has ngrok been around?
The first prototype for ngrok was committed on [March 20th, 2013](https://github.com/inconshreveable/ngrok/commit/8f4795ecac7f92c6b5a8c8970c65f26e5315fe4e).
## Why is my vendor asking me to install ngrok for 'site-to-site connectivity'?
Your vendor wants to create a secure persistent connection between your network and theirs, which allows them to access and take action on your services and data.
For details about what ngrok is, how to install the ngrok agent, and how to work with your vendor to implement adequate security practices, see the [end customer installation guide](/docs/gateway/site-to-site-connectivity/end-customers/).
# Agent CLI TLS Termination
Source: https://ngrok.com/docs/gateway/agent/agent-tls-termination
Terminate TLS at the ngrok Agent CLI rather than at ngrok's network, so traffic stays encrypted end to end all the way to your upstream service.
Agent TLS termination enables you to secure your traffic with end-to-end encryption without needing to reconfigure your server.
If your service doesn't support TLS termination, you can still use Agent TLS termination with [Zero-Knowledge TLS](/docs/gateway/domains/tls-termination/#end-to-end-encryption).
The following instructions will guide you through setting up Agent TLS termination with ngrok.
## What you'll need
* Ensure you have [openssl](https://docs.openiam.com/docs-4.2.1.3/appendix/2-openssl) installed.
## 1. Generate a cert and key pair
The following command:
1. Generates a new certificate signing request (CSR) for a 4096-bit RSA key pair.
* The key is saved to `your-key.key`.
2. Creates a self-signed certificate which:
* Is in x509 format and uses the SHA-256 hash algorithm.
* Is valid for 365 days.
* Is saved to `your-cert.crt`.
```bash theme={null}
openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -noenc -out your-cert.crt -keyout your-key.key
```
## 2. Configure your endpoint
You can configure your endpoint with an [agent configuration file](/docs/gateway/agent/config/). To create a new configuration file with your generated cert and key pair, run the following command:
```bash theme={null}
ngrok config add-authtoken you-authtoken
```
Your generated configuration file should resemble the following:
```yaml theme={null}
version: 3
agent:
authtoken: your-authtoken
endpoints:
- name: demo-tls
url: tls://your-domain.ngrok.app
upstream:
url: 12345
agent_tls_termination:
server_certificate: /path/to/your-cert.crt
server_private_key: /path/to/your-key.key
```
You can run `ngrok config edit` to open the configuration file in your default text editor. [Learn more about the `ngrok config` command](/docs/gateway/agent/cli/#ngrok-config).
### Optional: require client certificates (mTLS) at the agent
To make the agent authenticate clients as part of the TLS handshake, add one or more Certificate Authorities to the `agent_tls_termination` block with `mutual_tls_certificate_authorities`.
The agent will reject any client whose certificate isn't signed by one of the listed CAs.
```yaml theme={null}
version: 3
agent:
authtoken: your-authtoken
endpoints:
- name: demo-tls
url: tls://your-domain.ngrok.app
upstream:
url: 12345
agent_tls_termination:
server_certificate: /path/to/your-cert.crt
server_private_key: /path/to/your-key.key
mutual_tls_certificate_authorities:
- /path/to/your-ca-cert.crt
```
See [`agent_tls_termination.mutual_tls_certificate_authorities`](/docs/gateway/agent/config/v3#agent_tls_termination-mutual_tls_certificate_authorities) for the full reference.
This is different from mTLS terminated at the ngrok edge via [the `terminate-tls` Traffic Policy action](/docs/gateway/domains/mtls-termination/).
With agent-side mTLS, the client certificate is validated by your agent; traffic between the ngrok edge and your agent is still carried over the agent's secure TLS connection to ngrok, but client-certificate authentication is not performed on that hop.
## 3. Start your endpoint
Next, use `ngrok start endpoint_name_here` in the terminal to start an endpoint using the settings in your agent configuration file, as shown below:
```bash theme={null}
ngrok start demo-tls
```
## 4. Start your upstream server
Start an upstream server on the specified port (for example, `12345`) to handle incoming requests. The following example uses Python, but you can use any language or framework depending on your requirements.
```python theme={null}
import socket
host='127.0.0.1'
port=12345
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
print(f"Server started on {host}:{port}")
server.listen(1)
while True:
client, client_address = server.accept()
print(f"Connection established with {client_address}")
client.sendall(b"hello, world!")
client.close()
print(f"Connection with {client_address} closed")
```
## 5. Try connecting to your endpoint
The following example uses `openssl s_client` to initiate an SSL/TLS client connection to your upstream server without a certificate.
```bash theme={null}
openssl s_client -quiet -connect your-domain.ngrok.app:443 -verify_return_error
```
```bash theme={null}
Connecting to 2600:1f16:d83:1200::6e:0
depth=0 C=AU, ST=Some-State, O=Internet Widgets Pty Ltd, CN=your-domain.ngrok.app
verify error:num=18:self-signed certificate
408FB6F801000000:error:0A000086:SSL routines:tls_post_process_server_certificate:certificate verify failed:ssl/statem/statem_clnt.c:2093:
```
The following example uses `openssl s_client` to initiate an SSL/TLS client connection to your upstream server with a certificate.
```bash theme={null}
openssl s_client -quiet -connect your-domain.ngrok.app:443 -verify_return_error -CAfile your-cert.crt
```
```bash theme={null}
Connecting to 2600:1f16:d83:1200::6e:0
depth=0 C=AU, ST=Some-State, O=Internet Widgets Pty Ltd, CN=your-domain.ngrok.app
verify return:1
hello, world!%
```
The extra arguments added to the command suppress most of the output so that only the data exchanged with the server will be displayed.
# ngrok Agent CLI API
Source: https://ngrok.com/docs/gateway/agent/api
The ngrok Agent CLI exposes a local HTTP API for collecting status and metrics, capturing and replaying requests, and starting or stopping endpoints while it runs.
## Overview
The ngrok agent exposes an HTTP API that enables you to:
* Collect status and metrics information
* Collect and replay captured requests
* Start and stop endpoints dynamically
If you need to programmatically control the ngrok agent, consider using one of the [Agent SDKs](/docs/agent-sdks/) instead of the API.
## Base URL and authentication
| | |
| - | - |
| Base URL | `http://127.0.0.1:4040/api` |
| Authentication | **None** |
The ngrok agent API is exposed as part of ngrok's local web inspection interface.
Because it's served on a local interface, the API has no authentication.
The Base URL will change if you override `web_addr` in your configuration file.
### Access the root API resource of a running ngrok Agent
```sh theme={null}
curl http://localhost:4040/api/
```
## Supported content types
Request parameters must be encoded to the API using `application/json`.
Ensure that your client sets the request's `Content-Type` header appropriately.
All responses returned by the API are `application/json`.
## Versioning and API stability
The ngrok agent API guarantees that breaking changes to the API will never be made unless the caller explicitly opts in to a newer version.
The mechanism by which a caller opts into a new version of the API will be determined in the future when it becomes necessary.
Examples of non-breaking changes to the API that will not be opt-in include:
* The addition of new resources
* The addition of new methods to existing resources
* The addition of new fields on existing resource representations
* Bug fixes that change the API to match documented behavior
## List tunnels
This API is deprecated.
Use the [list endpoints API](#list-endpoints) instead.
Returns a list of running tunnels with status and metrics information.
### Request
`GET/api/tunnels`
### Parameters
| | |
| - | - |
| `tunnels` | List of all running tunnels. See the [Tunnel detail](#tunnel-detail) resource for docs on the parameters of each tunnel object. |
### Example response
```
{
"tunnels": [
{
"name": "command_line",
"uri": "/api/tunnels/command_line",
"public_url": "https://d95211d2.ngrok.app",
"proto": "https",
"config": {
"addr": "localhost:80",
"inspect": true
},
"metrics": {
"conns": {
"count": 0,
"gauge": 0,
"rate1": 0,
"rate5": 0,
"rate15": 0,
"p50": 0,
"p90": 0,
"p95": 0,
"p99": 0
},
"http": {
"count": 0,
"rate1": 0,
"rate5": 0,
"rate15": 0,
"p50": 0,
"p90": 0,
"p95": 0,
"p99": 0
}
}
}
],
"uri": "/api/tunnels"
}
```
## Start tunnel
Dynamically starts a new tunnel on the ngrok agent.
The request body parameters are the same as those you would use to define the tunnel in the configuration file.
### Request
`POST/api/tunnels`
### Parameters
Parameter names and behaviors are identical to those those defined in the configuration file.
Use the [tunnel definitions](/docs/gateway/agent/config/v2/#tunnel-configurations) section as a reference for configuration parameters and their behaviors.
### Example request body
```
{
"addr": "22",
"proto": "tcp",
"name": "ssh"
}
```
### Response
`201 Created` status code with a response body describing the started tunnel.
See the [Tunnel detail](#tunnel-detail) resource for docs on the parameters of the response object.
### Example response
```
{
"name": "",
"uri": "/api/tunnels/",
"public_url": "tcp://0.tcp.ngrok.io:53476",
"proto": "tcp",
"config": {
"addr": "localhost:22",
"inspect": false
},
"metrics": {
"conns": {
"count": 0,
"gauge": 0,
"rate1": 0,
"rate5": 0,
"rate15": 0,
"p50": 0,
"p90": 0,
"p95": 0,
"p99": 0
},
"http": {
"count": 0,
"rate1": 0,
"rate5": 0,
"rate15": 0,
"p50": 0,
"p90": 0,
"p95": 0,
"p99": 0
}
}
}
```
## Tunnel detail
Get status and metrics about the named running tunnel.
### Request
`GET/api/tunnels/:name`
### Example response
```
{
"name": "command_line",
"uri": "/api/tunnels/command_line",
"public_url": "https://ac294125.ngrok.app",
"proto": "https",
"config": {
"addr": "localhost:80",
"inspect": true
},
"metrics": {
"conns": {
"count": 0,
"gauge": 0,
"rate1": 0,
"rate5": 0,
"rate15": 0,
"p50": 0,
"p90": 0,
"p95": 0,
"p99": 0
},
"http": {
"count": 0,
"rate1": 0,
"rate5": 0,
"rate15": 0,
"p50": 0,
"p90": 0,
"p95": 0,
"p99": 0
}
}
}
```
## Stop tunnel
Stop a running tunnel.
### Request
`DELETE/api/tunnels/:name`
### Response
`204 No Content` status code with an empty body.
## List endpoints
Returns a list of running endpoints with status and metrics information.
### Request
`GET/api/endpoints`
### Response
`200 OK` status code with a JSON response containing an array of endpoint objects.
### Example response
```
{
"endpoints": [
{
"name": "command_line",
"uri": "/api/endpoints/command_line",
"url": "https://871e40f2d4c2.ngrok.paid.lan",
"upstream": {
"url": "http://localhost:8000",
"protocol": "https"
},
"inspect": true,
"traffic_policy": "on_http_request:\n - actions:\n - type: custom-response\n config:\n status_code: 200\n body: Hello, World!\n",
"pooling_enabled": true
}
]
}
```
## Endpoint detail
Get status and metrics about the named running endpoint.
### Request
`GET/api/endpoints/:name`
### Response
`200 OK` status code with endpoint JSON for success.
`404 Not Found` if the provided name doesn't correspond to an endpoint.
### Example response
```
{
"name": "command_line",
"uri": "/api/endpoints/command_line",
"url": "https://871e40f2d4c2.ngrok.paid.lan",
"upstream": {
"url": "http://localhost:8000",
"protocol": "https"
},
"inspect": true,
"traffic_policy": "on_http_request:\n - actions:\n - type: custom-response\n config:\n status_code: 200\n body: Hello, World!\n",
"pooling_enabled": true,
"metrics": {
"conns": {
"count": 0,
"gauge": 0,
"rate1": 0,
"rate5": 0,
"rate15": 0,
"p50": 0,
"p90": 0,
"p95": 0,
"p99": 0
},
"http": {
"count": 0,
"rate1": 0,
"rate5": 0,
"rate15": 0,
"p50": 0,
"p90": 0,
"p95": 0,
"p99": 0
}
}
}
```
## Create endpoint
Dynamically creates a new endpoint on the ngrok agent.
### Request
`POST/api/endpoints`
### Response
`201 Created` on success.
`400 Bad Request` for malformed payloads.
### Example request body
```
{
"name": "my_awesome_tunnel",
"url": "https://iamawesome.ngrok.paid.lan",
"upstream": {
"url": "8001"
},
"pooling_enabled": true
}
```
## Update endpoint
Updates an existing endpoint or creates a new one if it doesn't exist.
### Request
`PUT/api/endpoints/:name`
### Response
`200 OK` if an existing endpoint is updated.
`201 Created` if an endpoint is created.
`400 Bad Request` for malformed payloads.
### Example request body
```
{
"name": "command_line",
"uri": "/api/endpoints/command_line",
"url": "https://871e40f2d4c2.ngrok.paid.lan",
"upstream": {
"url": "http://localhost:8000",
"protocol": "https"
},
"inspect": true,
"traffic_policy": "on_http_request:\n - actions:\n - type: custom-response\n config:\n status_code: 200\n body: Hello, World!\n",
"pooling_enabled": true
}
```
## Delete endpoint
Stop a running endpoint.
### Request
`DELETE/api/endpoints/:name`
### Response
`204 No Content` for successful delete.
`404 Not Found` if trying to delete a nonexistent endpoint.
## List captured requests
Returns a list of all HTTP requests captured for inspection.
This will only return requests that are still in memory—ngrok evicts captured requests when their memory usage exceeds `inspect_db_size`.
### Request
`GET/api/requests/http`
### Query parameters
| | |
| - | - |
| `limit` | Maximum number of requests to return. |
| `tunnel_name` | Filter requests only for the given tunnel name. |
### Example request
```sh theme={null}
curl http://localhost:4040/api/requests/http?limit=50
```
### Response
| | |
| - | - |
| `requests` | List of captured requests. See the [Captured Request Detail](#captured-request-detail) resource for docs on the request objects. |
### Example response
```
{
"uri": "/api/requests/http",
"requests": [
{
"uri": "/api/requests/http/548fb5c700000002",
"id": "548fb5c700000002",
"tunnel_name": "command_line (http)",
"remote_addr": "192.168.100.25",
"start": "2014-12-15T20:32:07-08:00",
"duration": 3893202,
"request": {
"method": "GET",
"proto": "HTTP/1.1",
"headers": {
"Accept": [
"*/*"
],
"Accept-Encoding": [
"gzip, deflate, sdch"
],
"Accept-Language": [
"en-US,en;q=0.8"
],
"Connection": [
"keep-alive"
],
"User-Agent": [
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36"
],
"X-Original-Host": [
"c159663f.ngrok.app"
]
},
"uri": "/favicon.ico",
"raw": ""
},
"response": {
"status": "502 Bad Gateway",
"status_code": 502,
"proto": "HTTP/1.1",
"headers": {
"Content-Length": [
"1716"
]
},
"raw": ""
}
}
]
}
```
## Replay captured request
Replays a request against the local endpoint of a tunnel.
### Request
`POST/api/requests/http`
### Parameters
| | |
| - | - |
| `id` | ID of request to replay. |
| `tunnel_name` | Name of the tunnel to play the request against. If unspecified, the request is played against the same tunnel it was recorded on. |
### Example request
```sh theme={null}
curl -H "Content-Type: application/json" -d '{"id": "548fb5c700000002"}' http://localhost:4040/api/requests/http
```
### Response
`204 No Content` status code with an empty body.
## Delete captured requests
Deletes all captured requests.
### Request
`DELETE/api/requests/http`
### Response
`204 No Content` status code with no response body.
## Captured request detail
Returns metadata and raw bytes of a captured request.
The raw data is base64-encoded in the JSON response.
The `response` value may be `null` if the local server hasn't responded to a request yet.
### Request
`GET/api/requests/http/:request_id`
### Example response
```
{
"uri": "/api/requests/http/548fb5c700000002",
"id": "548fb5c700000002",
"tunnel_name": "command_line (http)",
"remote_addr": "192.168.100.25",
"start": "2014-12-15T20:32:07-08:00",
"duration": 3893202,
"request": {
"method": "GET",
"proto": "HTTP/1.1",
"headers": {
"Accept": [
"*/*"
],
"Accept-Encoding": [
"gzip, deflate, sdch"
],
"Accept-Language": [
"en-US,en;q=0.8"
],
"Connection": [
"keep-alive"
],
"User-Agent": [
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36"
],
"X-Original-Host": [
"c159663f.ngrok.app"
]
},
"uri": "/favicon.ico",
"raw": ""
},
"response": {
"status": "502 Bad Gateway",
"status_code": 502,
"proto": "HTTP/1.1",
"headers": {
"Content-Length": [
"1716"
]
},
"raw": ""
}
}
```
## Agent status
Get status and metrics about the running agent.
### Request
`GET /api/status`
### Example request
```sh theme={null}
curl http://localhost:4040/api/status
```
### Response
`200 OK` status code with a JSON response describing the status of the agent.
### Example response
```
{
"status": "online",
"agent_version": "3.9.0",
"session": {
"legs": [
{
"region": "au",
"latency": "87ms"
}
]
},
"uri": "/api/status"
}
```
# Agent API Keys
Source: https://ngrok.com/docs/gateway/agent/api-keys
Add an API key to the agent so you can query and manage domains, endpoints, and other account resources from the command line.
The ngrok agent contains a [complete CLI for the ngrok API](/docs/gateway/agent/cli-api/).
To use it, [create an API key on your ngrok dashboard](https://dashboard.ngrok.com/api-keys) and then run:
```bash theme={null}
ngrok config add-api-key
```
After you add the API key, try querying your list of domains or online endpoints:
```bash theme={null}
ngrok api endpoints list
ngrok api reserved-domains list
```
# Agent Authtokens
Source: https://ngrok.com/docs/gateway/agent/authtokens
Authenticate an agent with your ngrok account using an authtoken, and use ACLs to scope which endpoints and resources that credential is allowed to use.
The ngrok agent authenticates with an authtoken.
[Your authtoken is available on the ngrok dashboard](https://dashboard.ngrok.com/get-started/your-authtoken).
Add your authtoken to the ngrok agent with the following command:
```bash theme={null}
ngrok config add-authtoken
```
This command updates the `authtoken` property in your [ngrok configuration file](/docs/gateway/agent/config).
Use a separate authtoken for each agent you configure. You can [provision additional authtokens on your ngrok dashboard](https://dashboard.ngrok.com/authtokens) or [via API](/docs/gateway/agent/config/v3/#authtoken). Separate authtokens isolate the security risk
if an authtoken is compromised. It also allows you to configure
ACLs on a per agent basis.
When you provision a new authtoken, the full token is only displayed once. As a security
feature, ngrok does not store a recoverable representation of the token.
## Authtoken ACLs
Authtoken ACLs restrict what actions an ngrok agent connecting with that
authtoken is allowed to take. You may define multiple ACLs. Authtokens with no
ACLs may take all actions. The following ACLs are supported:
| Example | Description |
| - | - |
| `bind:foo.ngrok.app` | The agent may only create an endpoint on `foo.ngrok.app` |
| `bind:*.example.com` | The agent may only create endpoints on subdomains of `example.com` |
| `bind:foo=bar` | The agent may create a labeled endpoint with the label `foo=bar` |
| `bind:app=*` | The agent may create labeled endpoints with labels like `app=x` or `app=y` |
| `bind:*` | The agent may listen on all endpoints |
# ngrok Agent Changelog
Source: https://ngrok.com/docs/gateway/agent/changelog
Release notes for every version of the ngrok agent, covering new features, fixes, and the breaking changes between major versions.
## v3
### ngrok Agent 3.39.11 \[2026-08-12]
* Moved to ngrok-go v2.1.1
### ngrok Agent 3.39.10 \[2026-07-22]
* Corrected stale `dashboard.ngrok.com` links shown in `ngrok --help` and CLI error output.
### ngrok Agent 3.39.9 \[2026-06-23]
* Only includes internal release pipeline changes
### ngrok Agent 3.39.8 \[2026-06-16]
* Remove broad filesystem write virtualization permission for ngrok on the Microsoft App Store
### ngrok Agent 3.39.7 \[2026-06-09]
* Update libraries and Go version to patch most recent round of CVEs
* Add new `crl_url` configuration option to allow using a custom CRL
### ngrok Agent 3.39.6 \[2026-06-01]
* Updated OpenTelemetry dependencies to patch security vulnerabilities
### ngrok Agent 3.39.5 \[2026-05-26]
* Internal improvements to the build process, no functional changes
### ngrok Agent 3.39.3 \[2026-05-21]
* Patch various CVEs
### ngrok Agent 3.39.2 \[2026-05-15]
* Various security improvements
### ngrok Agent 3.39.1 \[2026-04-28]
* Fix crash on startup for Windows Store builds
### ngrok Agent 3.39.0 \[2026-04-27]
* Added support for AI Gateway provider keys
### ngrok Agent 3.38.0 \[2026-04-17]
* Upgraded internal dependencies
### ngrok Agent 3.37.6 \[2026-04-09]
* Internal improvements to the build process, no functional changes
### ngrok Agent 3.37.3 \[2026-03-26]
* Internal improvements to the build process, no functional changes
### ngrok Agent 3.37.2 \[2026-03-10]
* Fix a regression in macOS configuration paths
### ngrok Agent 3.37.1 \[2026-03-06]
* Disable updates for Windows App Store builds
* Fix config file location for Microsoft Store installs
* Add `ai-gateway-api-keys` CLI commands
### ngrok Agent 3.36.1 \[2026-02-12]
* Fix for upstream.proxy\_protocol field in V3 configuration
### ngrok Agent 3.36.0 \[2026-02-03]
* Change agent self update link (was: `update.equinox.io`, is now: `update.ngrok-agent.com`).
* Deprecated flags that are made obsolete by Traffic Policies.
Such flags can still be used, but aren't shown in `--help` output
and will display deprecation warnings if used.
* Hid the deprecated `ngrok tunnel` command from `--help` output.
Please use `ngrok http`, `ngrok tcp`, or `ngrok tls` instead.
### ngrok Agent 3.35.0 \[2026-01-12]
* Honor custom DNS if provided.
### ngrok Agent 3.34.1 \[2025-12-11]
* Fix a bug with the `*-file` and `*-url` flags that was overwriting flag values with nil
### ngrok Agent 3.34.0 \[2025-12-05]
* Deprecate the `--terminate-at` command-line option
### ngrok Agent 3.33.1 \[2025-11-25]
* Fix a bug where inspector is filled with error logs when not in use
### ngrok Agent 3.33.0 \[2025-11-12]
* Fix a bug that could result in pooling being disabled via the API or Dashboard
### ngrok Agent 3.32.0 \[2025-10-23]
* Allow local\_storage config option to disable local inspector
* Allow setting RLIMIT\_NOFILE when running as a systemd service
### ngrok Agent 3.31.0 \[2025-10-20]
* Rename Bot users to Service users.
* Update billing urls.
* Can now use vault name or id when creating a secret.
### ngrok Agent 3.30.0 \[2025-09-23]
* A new agent HTTP API, `/api/endpoints`, has been introduced that corresponds to the [agent config version 3 format](/docs/gateway/agent/config/v3/)
* Endpoints and tunnels deleted via the agent API will be properly reflected in the Dashboard
### ngrok Agent 3.29.0 \[2025-09-17]
* Blocked creating tunnels with duplicate names via the agent HTTP API
### ngrok Agent 3.28.0 \[2025-09-11]
* Updated Docker build base
* Restored support for `PROXY` in TCP/TLS tunnels
### ngrok Agent 3.27.0 \[2025-08-28]
* Optimized agent ui.
* Added get-secrets-by-vault path to vaults api 🤫
### ngrok Agent 3.26.0 \[2025-08-07]
* Added support for supplying a Traffic Policy to endpoints created with `ngrok http` and `ngrok api` using the `--traffic-policy-url` flag
### ngrok Agent 3.25.1 \[2025-08-01]
* Allow specifying a file for secrets, rather than requiring them to be passed on the command line
### ngrok Agent 3.25.0 \[2025-07-24]
* Debian Bookworm support added.
* This release is functionally identical to 3.24.0.
### ngrok Agent 3.24.0 \[2025-07-17]
This version includes critical security fixes for users of mTLS that exists in
agent version 3.19 through 3.23. ngrok **strongly** encourages anyone who uses
mTLS to upgrade immediately.
* Allow for configuring maximum and minimum TLS versions
* Allow enforcing mTLS certificate checks
### ngrok Agent 3.23.3 \[2025-06-26]
* Updates and improvements to `--help` text
### ngrok Agent 3.23.2 \[2025-06-20]
* Improve Windows diagnostics
### ngrok Agent 3.23.1 \[2025-06-10]
* Correct names for vaults and secrets API commands.
### ngrok Agent 3.23.0 \[2025-06-05]
* Add API command support for vaults and secrets.
* Add audit events to vaults and secrets.
### ngrok Agent 3.22.1 \[2025-03-20]
* Fix CLI help/descriptions for endpoints create command.
### ngrok Agent 3.22.0 \[2025-03-20]
* Fixed a bug where TCP KeepAlive support could cause a crash on old versions of Windows
### ngrok Agent 3.21.0 \[2025-03-13]
* Add TCP KeepAlive configuration option.
### ngrok Agent 3.20.0 \[2025-02-20]
* Add bindings to v3 configs.
### ngrok Agent 3.19.1 - \[2024-1-23]
* Improve ux of CLI errors.
* Correct error scheme on errors.
### ngrok Agent 3.19.0 - \[2024-12-19]
* Add tls termination to v3 agent configs.
### ngrok Agent 3.18.4 - \[2024-11-11]
* Fixed a bug causing the `--url` flag require an explicit scheme.
### ngrok Agent 3.18.3 - \[2024-11-07]
* Fixed agent diagnose return codes.
### ngrok Agent 3.18.2 - \[2024-10-31]
* Fixed ngrok diagnose --region all report.
* Fixed scheme proto defaulting.
* Added 128 character limit to usernames for agent basic auth.
### ngrok Agent 3.18.1 - \[2024-10-24]
* Adds binary execution path to the host system metrics collected.
* Fixed a bug where 4 character time zones were not handled properly in the console UI.
### ngrok Agent 3.18.0 - \[2024-10-17]
* Added `--name` field for endpoints and tunnels when created from the agent config or CLI.
### ngrok Agent 3.17.0 - \[2024-10-10]
* Added endpoint create/update/delete subcommands to the ngrok api command.
* Added support for policy phases like `on_tcp_connect`, `on_http_request` and `on_http_response`.
* Fixed a bug where TLS was incorrectly passed as the endpoint proto rather than HTTP(S).
### ngrok Agent 3.16.1 - \[2024-10-03]
* Added windows arm64 agent binary.
### ngrok Agent 3.16.0 - \[2024-09-09]
* Releasing the features originally released by 3.15.0
* Added `--url` agent CLI flag for creation of HTTP(S), TLS, and TCP protocol endpoints.
* Deprecated `--domain`, `--scheme`, and `--remote-addr` agent CLI flags, which have been replaced by `--url`.
* Added `--metadata` and `--description` agent CLI flags when using `--url`.
* Added `endpoints:` as a new field used for [endpoint creation](/docs/gateway/agent/config/v3/).
* A new `agent:` field has been added to the agent configuration format for V3.
* v3 supports *both* tunnels and endpoints.
Tunnels are now considered deprecated when using config v3.
* Some agent configuration fields have been renamed in v3.
* v2 is still supported, but doesn't support the new `endpoints:` , or `agent:` fields.
* Added support for [endpoint fields](/docs/api-reference/endpoints/list) in ngrok's `api`.
* Update `config` commands to support new configuration version 3, including `upgrade`, `add-authtoken`, and `add-api-key`
### ngrok Agent 3.15.1 - \[2024-08-29]
* Restores the functionality and compatibility for version 3.14.0 due to bugs in the previous release.
An updated version with the changes from 3.15.0 will be released early next week.
### \[UNSTABLE] ngrok Agent 3.15.0 - \[2024-08-29]
* Added `--url` agent CLI flag for creation of HTTP(S), TLS, and TCP protocol endpoints.
* Deprecated `--domain`, `--scheme`, and `--remote-addr` agent CLI flags, which have been replaced by `--url`.
* Added `--metadata` and `--description` agent CLI flags when using `--url`.
* Added `endpoints:` as a new field used for [endpoint creation](/docs/gateway/agent/config/v3/).
* A new `agent:` field has been added to the agent configuration format for V3.
* v3 supports *both* tunnels and endpoints.
Tunnels are now considered deprecated when using config v3.
* Some agent configuration fields have been renamed in v3.
* v2 is still supported, but doesn't support the new `endpoints:` , or `agent:` fields.
* Added support for [endpoint fields](/docs/api-reference/endpoints/list) in ngrok's `api`.
### ngrok Agent 3.14.1 - \[2024-08-22]
* Resolved an issue with mTLS detection.
### ngrok Agent 3.14.0 - \[2024-08-01]
* Added support for `traffic_policy` field in agent config for Traffic Policy configuration.
* Deprecated `policy`
* Added `EndpointTrafficPolicy` module to Edge API.
### ngrok Agent 3.13.0 - \[2024-07-15]
* In some cases, adds additional headers on error responses to ngrok that can be used to customize the content.
### ngrok Agent 3.12.1 - \[2024-07-11]
* Fixed a bug in `ngrok diagnose` that would cause a panic if a server IP and the agent had TLS connectivity issues.
* Added `--traffic-policy-file` flag that accepts Traffic Policy configuration for HTTP, TCP, or TLS traffic.
* Deprecated `--policy-file` flag
### ngrok Agent 3.12.0 - \[2024-06-27]
* Errors now have links to ngrok error page.
### ngrok Agent 3.11.0 - \[2024-06-13]
* `ngrok http` now has timestamps for incoming requests.
### ngrok Agent 3.10.1 - \[2024-06-06]
* Requests to TLS endpoints using `proto: tls` and `terminate_at: agent` succeed after the agent session goes through a reconnection.
### ngrok Agent 3.10.0 - \[2024-05-23]
* **ACTION MAY BE REQUIRED**: The domain used for Certificate Revocation List (CRL) checks is now `crl.ngrok-agent.com` to align it with the domain used for session connections.
This may require changes to your firewall or proxy settings to allow this outbound connection on port 80, or setting `crl_noverify: true` in the agent config file.
* Added CLI API support for [Service Users](/docs/iam/service-users/).
### ngrok Agent 3.9.0 - \[2024-04-24]
* Added a `/api/status` endpoint to the local agent API that returns the agent's current status
* The agent will check the Certificate Revocation List (CRL) on Session initiation.
If a custom Connect URL is being used that has an invalid CRL in the chain, the `crl_noverify: true` option can be used to override this check, if desired
* Certificate Revocation List (CRL) checking for certain Let's Encrypt certificate chains has been fixed
### ngrok Agent 3.8.0 - \[2024-03-14]
* Added `json` support to Traffic Policy configuration
* Moved to ngrok-go v1.9.1
### ngrok Agent 3.7.0 - \[2024-03-07]
* Fixed an issue where `ngrok diagnose --region all` would return an error for `eu-lon-1`
* Fixed a typo in default usage output
* Moved to `ngrok-go` v1.9.0
### ngrok Agent 3.6.0 - \[2024-02-06]
* Added `--policy-file` flag that accepts Traffic Policy configuration for HTTP, TCP, or TLS traffic.
* Added support for `policy` field in agent config for Traffic Policy configuration.
* Added concise help text when `ngrok` is run without any args
* Removed support for Windows 7 and Windows 8 (support for Windows 7 and 8 was dropped in [Go 1.21](https://tip.golang.org/doc/go1.21#windows))
### ngrok Agent 3.5.0 - \[2023-12-01]
* The `--region` flag has been deprecated, ngrok automatically chooses the region with lowest latency
* The upstream tls configs have been renamed, with backwards compatibility:
* `--verify-upstream-tls` is now `--upstream-tls-verify`
* `--upstream-ca-path` is now `--upstream-tls-verify-cas`
* An option for `--app-protocol` of the upstream, which can be set to `http2`, has been added
* The `StopTunnel` message is now handled by the agent
### ngrok Agent 3.4.0 - \[2023-11-03]
* Added support for upstream TLS verification when forwarding to `https://` or `tls://` addresses.
* `--verify-upstream-tls` enables TLS verification of server TLS certificates
* `--upstream-ca-path` sets the certificate authority used to verify upstream server certificates
### ngrok Agent 3.3.5 - \[2023-09-26]
* Added support for the User Agent Filter module (now deprecated by Traffic Policy) that allows or denies traffic to HTTPS endpoints based on incoming user agents.
* Added `--ua-filter-allow` and `--ua-filter-deny` flags that accept a list of regular expression strings
### ngrok Agent 3.3.4 - \[2023-08-18]
* Fixed a bug where the agent running as a service would log to syslog even when another log destination was specified
* Fixed a bug where the agent could incorrectly ignore `dns_resolver_ips`
### ngrok Agent 3.3.3 - \[2023-08-11]
* Added new `us-cal-1` region which will reduce latency for users in the western half of North America
### ngrok Agent 3.3.2 - \[2023-07-27]
* Added support for the [Datadog event destination](/docs/integrations/event-destinations/datadog-event-destination) in `ngrok api`
### ngrok Agent 3.3.1 - \[2023-06-05]
* Fixed a bug where colons in request header and response header values were not allowed (for example, `--request-header-add "Access-Control-Allow-Origin:https://developer.mozilla.org"`)
* Fixed a bug introduced in v3.3.0 where `--terminate-at edge` wasn't using the correct TLS certificate
### ngrok Agent 3.3.0 - \[2023-05-09]
* Added new default tunnel ingress names: the agent now connects to [`connect.ngrok-agent.com`](/docs/gateway/security-dev-productivity/securing-your-tunnels/#blocking-non-corporate-accounts) when starting a session
* Improved `ngrok diagnose` output to check that the DNS entry for `localhost` resolves
* Added the command `ngrok config add-server-addr` for configuring custom Connect URLs
* Re-wrote the tunnel and session backend to use the `ngrok-go` library
### ngrok Agent 3.2.2 - \[2023-03-27]
* Fixed a bug introduced in v3.2.1 with tab complete for command line flags
### ngrok Agent 3.2.1 - \[2023-03-13]
* Deprecated the `--subdomain` and `--hostname` flags.
* Updated all `--subdomain` and `--hostname` examples to use `--domain`.
* Fixed a bug where the agent didn't resolve local DNS correctly on macOS arm64
* Allow specifying ngrok `--region=auto` to pick the closest region (defaults to auto)
* Support for the `NGROK_API_KEY` environment variable when using the ngrok api subcommand
* `--log-format=json` now results in more output being formatted as json
### ngrok Agent 3.1.1 - \[2023-01-13]
* Expanded diagnosis coverage when running `ngrok diagnose` to include testing against all regions and additional debug information of the underlying system.
* Updated `--config` option to be accepted in any position with cli command.
* Fixed `ngrok config add-authtoken ` to also save the default version if it doesn't exist in the config file.
* Fixed rare race condition where agent would crash unexpectedly.
* Added DNS rebinding protection which includes [`web_allow_hosts`](/docs/gateway/agent/config/v3/#web-allow-hosts) configuration.
### ngrok Agent 3.1.0 - \[2022-09-14]
* Started signing Windows executables with a code signing certificate.
Includes polish for Windows executable properties like description and icon.
* Updated the root CA recognized by new agent versions.
Improves incident recovery and mitigation options.
### ngrok Agent 3.0.7 - \[2022-08-17]
* Added `--region` flag to the `ngrok diagnose` command.
Including support for `--region all` to diagnose all regions.
* Ignore the `--config` flag when passed to a command that doesn't support it.
### ngrok Agent 3.0.6 - \[2022-06-30]
* Fixed issues with replay not displaying requests in the ngrok Agent web UI, console UI, and API.
* Fixed null pointer issues with `ngrok diagnose` command.
### ngrok Agent 3.0.5 - \[2022-06-22]
* Fixed a formatting issue in the inspector web UI for the header navigation.
* Updated the start tunnel API to allow starting labeled tunnels using a list of strings as labels.
### ngrok Agent 3.0.4 - \[2022-05-27]
* Added the ability to provide messages to users via the agent console.
* `ngrok config edit` will now allow you to edit an invalid configuration file.
* Updated the display of the latency number in the console UI to be more human readable.
### ngrok Agent 3.0.3 - \[2022-04-26]
* Fixed a bug on Windows where running the agent from explorer didn't open a cmd prompt.
### ngrok Agent 3.0.2 - \[2022-04-11]
* Fixed a bug that wasn't allowing users to start tunnels via the API.
### ngrok Agent 3.0.1 - \[2022-04-04]
* Added `ngrok config edit` command to open the config file in your default editor.
* Removed invalid `--proxy-proto` flag from the `ngrok start` command.
* Added a migration to the `ngrok config upgrade` command to convert basic auth config parameters.
* The ngrok agent API will now error if invalid values are passed to it.
Previously it ignored them.
### ngrok Agent 3.0.0 - \[2022-03-28]
For more information about upgrading from previous versions of the agent to v3.0, see the [upgrade guide](/docs/gateway/agent/upgrade-v2-v3/).
* Fixed an issue where an agent would not reconnect after removing a reserved domain from your account.
* Added `ngrok completion` to enable autocomplete for the cli.
* Added `proxy_proto` option for enabling and specifying the [HAProxy's PROXY protocol version](https://www.haproxy.com/blog/haproxy/proxy-protocol/).
* Added the ability to set the `connect_interface` for the agent.
* Renamed `bind_tls` to `schemes`.
* The agent UI now display ping time.
* Added the `ngrok diagnose` command to the agent for troubleshooting connection issues.
* Added the `ngrok config` command for managing the configuration file.
* Added the ability to call the ngrok API from the agent using `ngrok api`.
* Added the `ngrok service` command to manage the ngrok agent as a service.
* All ngrok agent configuration files must now include a version number to indicate the format.
* Added the ability to start Labeled Tunnels to the agent that work with the new Tunnel Group backend.
* Renamed the "Clear" button to "Clear Requests" in the inspect UI to make it clear as to what it's doing.
* Fixed an issue where running `ngrok authtoken` would make changes to your tunnel definitions.
* The inspect UI will now pretty-print content types ending in +json.
* Fixed an issue where the inspect UI was adding unwanted HTML tags to JSON bodies when replayed.
* The ngrok agent now logs to stdout by default when `console_ui: false`.
* Command line arguments must use single hyphen for single letter options, and double hyphen for longer names.
* The ngrok agent now fails when there are keys in the config file it doesn't understand.
Previously it ignored unknown options.
* Using the `--host-header rewrite` option puts the original host header value into the `X-Forwarded-Host` header field instead of the `X-Original-Host` header in an attempt to be more standard.
* Combined `http_proxy` and `socks5_proxy` configuration options into a single option (
## v2
### ngrok Agent 2.3.x
If asked to forward to port 443, ngrok will now automatically forward HTTPS traffic instead of HTTP.
This change would only affect you if you previously ran a server accepting unencrypted HTTP on port 443.
To work around it, specify an explicit http URL if you need the old behavior: `ngrok http http://localhost:443`.
If run under sudo, the ngrok agent previously consulted the sudo-ing user's home directory file when looking for its default configuration file.
It now consults the home directory of the assumed user.
To workaround this, you may specify an explicit configuration file location with the `-config` option.
### ngrok Agent 2.2.x
The ngrok agent API no longer accepts `application/x-www-form-urlencoded` request bodies.
In practice, this only affects the `/api/requests/http/:id` endpoint because posting to the `/api/tunnels` endpoint with this type of request body previously caused ngrok to crash.
This change was made to help protect against maliciously crafted web pages that could cause a user to inadvertently interact with their local ngrok API.
### ngrok Agent 2.1.x
Behavior changes for `http` and `tls` tunnels defined in the configuration file or started via the API that don't have a `subdomain` or `hostname` property.
```yaml theme={null}
tunnels:
webapp:
proto: http
addr: 80
```
Given this example tunnel configuration, behavior will change in the following ways.
##### Old behavior
Starts a tunnel using the name of the tunnel as the subdomain resulting in the URL `http://webapp.ngrok.app`
##### New behavior
Starts a tunnel with a random subdomain, for example a URL like `http://d95211d2.ngrok.app`
##### How to keep the old behavior
Add a `domain` property with the same name as the tunnel:
```yaml theme={null}
tunnels:
webapp:
proto: http
addr: 80
domain: webapp.ngrok.app
```
# ngrok Agent Command Line Interface (CLI)
Source: https://ngrok.com/docs/gateway/agent/cli
# ngrok Agent Command Line Interface (CLI)
The ngrok agent CLI offers built-in commands for interfacing with the ngrok API. These API commands have been separated into
the [ngrok agent CLI API page](/docs/gateway/agent/cli-api) for convenience. For more information about the ngrok API and interfacing with it directly, see [the ngrok api page](/docs/gateway/agent/api).
## ngrok
ngrok puts network services, apps and APIs online.
ngrok exposes local networked services behinds NATs and firewalls to the
public internet over a secure tunnel. Share local websites, build/test
webhook consumers and self-host personal services.
Detailed help for each command is available by adding '--help' to any command or with
the 'ngrok help' command.
Open [https://dashboard.ngrok.com/traffic-inspector](https://dashboard.ngrok.com/traffic-inspector) to inspect traffic through your endpoints.
### Usage
```sh theme={null}
ngrok [command] [flags]
```
### Example
```sh theme={null}
# forward http traffic from assigned public URL to local port 80
ngrok http 80
# choose a URL instead of random assignment
ngrok http 8080 --url https://baz.ngrok.dev
# manipulate traffic to your endpoint with a traffic policy file
ngrok http 8080 --url https://baz.ngrok.dev --traffic-policy-file tp.yml
# forward to another address on the network instead of a local port
ngrok http foo.local:3000
# forward to a local https server
ngrok http https://localhost:8443
# forward TCP traffic (e.g. ssh) with an assigned public address
ngrok tcp 22
# load balance (in two terminals)
ngrok http 80 --url https://api.example.com --pooling-enabled
ngrok http 80 --url https://api.example.com --pooling-enabled
# privately connect a service to the ngrok cloud.
# then forward traffic from other endpoints in your account to it
ngrok http 80 --url https://svc.internal
ngrok tcp 5432 --url tcp://postgres.internal:5432
# make your endpoint url addressable only from k8s clusters
# where you've installed the ngrok k8s operator
ngrok http 80 --url https://example.namespace --binding kubernetes
# start multiple endpoints defined in the config file
ngrok start foo bar baz
```
### SubCommands
| Command | Description |
| - | - |
| [api](#ngrok-api) | use ngrok agent as an api client |
| [completion](#ngrok-completion) | generates shell completion code for bash or zsh |
| [config](#ngrok-config) | update or migrate ngrok's configuration file |
| [credits](#ngrok-credits) | prints author and licensing information |
| [diagnose](#ngrok-diagnose) | diagnose connection issues |
| [http](#ngrok-http) | start an HTTP tunnel |
| [service](#ngrok-service) | run and control an ngrok service on a target operating system |
| [start](#ngrok-start) | start endpoints or tunnels by name from the configuration file |
| [tcp](#ngrok-tcp) | start a TCP tunnel |
| [tls](#ngrok-tls) | start a TLS tunnel |
| [update](#ngrok-update) | update ngrok to the latest version |
| [version](#ngrok-version) | print the version string |
### Flags
| Flag | Description |
| - | - |
| `--metadata` | opaque user-defined metadata for the tunnel session |
## ngrok completion
The `ngrok completion` command generates shell tab completion code for Bash or Zsh. This requires bash-completion or zsh-completions packages to be enabled in your shell.
You can add it to your current session with the command
```
. <(ngrok completion)
```
To enable them each time you start a new session, add the following to your `.bashrc` or `.zshrc` files:
```
if command -v ngrok &>/dev/null; then
eval "$(ngrok completion)"
fi
```
Once you add this to your profile, you'll need to `source ~/.bashrc` or `source ~/.zshrc` to enable it for your current session.
### Usage
```sh theme={null}
ngrok completion [flags]
```
### Example
```sh theme={null}
```
### Flags
| Flag | Description |
| - | - |
| `--config` | path to config files; they are merged if multiple |
## ngrok config
The config command gives a quick way to create or update ngrok's configuration
file. Use 'add-authtoken' or 'add-api-key' to set the corresponding properties.
Use 'check' to test a configuration file for validity. If you have an old
configuration file, you can also use 'upgrade' to automatically migrate to the
latest version.
### SubCommands
| Command | Description |
| - | - |
| [add-api-key](#ngrok-config-add-api-key) | save api key to configuration file |
| [add-authtoken](#ngrok-config-add-authtoken) | save authtoken to configuration file |
| [add-connect-url](#ngrok-config-add-connect-url) | adds the connect URL (connect\_url) to configuration file for custom agent ingress |
| [add-server-addr](#ngrok-config-add-server-addr) | alias of add-connect-url |
| [check](#ngrok-config-check) | check configuration file |
| [edit](#ngrok-config-edit) | edit configuration file |
| [upgrade](#ngrok-config-upgrade) | auto-upgrade configuration file |
### Flags
| Flag | Description |
| - | - |
| `--config` | path to config files; they are merged if multiple |
## ngrok config add-api-key
The add-api-key command modifies your configuration file to include
the specified api key.
The API key can be generated in the [API section of the ngrok dashboard](https://dashboard.ngrok.com/api).
### Usage
```sh theme={null}
ngrok config add-api-key TOKEN [flags]
```
### Example
```sh theme={null}
ngrok config add-api-key 1roPsn7AascHeO18mHcxRD3xT76_3ww7C9CDLYNgcdSYsscCB
```
### Flags
| Flag | Description |
| - | - |
| `--config` | save in this config file |
## ngrok config add-authtoken
The add-authtoken command modifies your configuration file to include
the specified authtoken.
ngrok requires that you sign up for an account to use many advanced
service features. In order to associate your client with an account,
it must pass a secret token to ngrok when it starts up. Instead of
passing this authtoken on every invocation, you may use this command
to save it into your configuration file so that your client always
authenticates you properly.
Additionally, this command saves the default config version, providing
a working config file out of the box.
You can find your authtoken in the [getting started section of the ngrok dashboard](https://dashboard.ngrok.com/get-started/your-authtoken).
The ngrok service requires that you [sign up for an account](https://dashboard.ngrok.com/) to connect with an agent. Some advanced service
features require a paid account. In order to associate your agent with an account, it must pass a secret token to the ngrok service when it starts up. Instead of passing this authtoken on every invocation, you may use this command to save it into your configuration file so that your agent always authenticates you properly.
### Usage
```sh theme={null}
ngrok config add-authtoken TOKEN [flags]
```
### Example
```sh theme={null}
ngrok config add-authtoken 1rlHSX3HqrqmOWZdeJ6bIv8rfuo_4cmS1QswRGyxcQD8NOukF
```
### Flags
| Flag | Description |
| - | - |
| `--config` | save in this config file |
## ngrok config add-connect-url
The add-connect-url command modifies your configuration file to include
the specified connect URL (connect\_url) used for custom agent ingress.
### Usage
```sh theme={null}
ngrok config add-connect-url agent.example.com:443 [flags]
```
### Example
```sh theme={null}
ngrok config add-connect-url agent.example.com:443
```
### Flags
| Flag | Description |
| - | - |
| `--config` | save in this config file |
## ngrok config add-server-addr
The ngrok config add-server-addr command updates the server address (server\_addr) in the configuration file. This is useful when your account is using Custom Agent Ingress and you need to configure the server\_addr to point to your new ingress domain.
*See Also*:
[`server_addr`](/docs/gateway/agent/config/#server-addr)
[Custom Agent Ingress](/docs/gateway/agent/connect-url/)
### Usage
```sh theme={null}
ngrok config add-server-addr agent.example.com:443 [flags]
```
### Example
```sh theme={null}
ngrok config add-server-addr agent.example.com:443
```
### Flags
| Flag | Description |
| - | - |
| `--config` | save in this config file |
## ngrok config check
Checks a configuration file for validity/correctness.
### Usage
```sh theme={null}
ngrok config check [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--config` | check this config file |
## ngrok config edit
Opens the configuration file in an editor defined by the EDITOR environment
variable, defaulting to nano or Notepad depending on OS.
### Usage
```sh theme={null}
ngrok config edit [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--config` | check this config file |
## ngrok config upgrade
Upgrade a configuration file to a version.
A backup file will be created with your original configuration file in
the same directory.
You can optionally pass a version to upgrade to. If the configuration file
version is missing, the upgrade command will add it. It also applies all
automatic transformations when upgrading versions. Attempting to downgrade
will result in an error.
By default this command will apply the transformations and display the
final file. Use --dry-run to preview changes before applying.
By default this command will not move any configuration files to their
new default location. Use --relocate to move the config file to the
default location.
### Usage
```sh theme={null}
ngrok config upgrade [version] [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--config` | upgrade this config file |
| `--dry-run` | preview the proposed changes |
| `--relocate` | relocates the config file to the default location |
## ngrok credits
Displays program credits and license information.
### Usage
```sh theme={null}
ngrok credits [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--config` | path to config files; they are merged if multiple |
## ngrok diagnose
Run tests to diagnose issues establishing connectivity to the ngrok cloud service.
Exits 0 if connectivity is OK, otherwise 1.
OPTIONS:
\--config strings path to config files; they are merged if multiple
-h, --help help for diagnose
-6, --ipv6 Enable testing of IPV6 addresses
-r, --region string ngrok server region \[auto, us, eu, au, ap, sa, jp, in, us-cal-1, eu-lon-1, all]
-w, --write-report string Write a JSON report
### Usage
```sh theme={null}
ngrok diagnose [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--6`, `--ipv6` | Enable testing of IPV6 addresses |
| `--r`, `--region` | ngrok server region \[auto, us, eu, au, ap, sa, jp, in, us-cal-1, eu-lon-1, all] |
| `--w`, `--write-report` | Write a JSON report |
| `--config` | path to config files; they are merged if multiple |
## ngrok http
Forward HTTP traffic from an ngrok endpoint URL to a local port, address
or URL.
The ngrok agent creates secure TLS connections to the ngrok cloud gateway
over which it creates an endpoint with a URL and forwards traffic received
on that URL over the TLS connections to the agent and then on to your local
service.
Specify a Traffic Policy to configure the ngrok cloud service to apply auth,
routing, security or other handling of the incoming HTTP traffic.
If you are not forwarding traffic to an http(s) server, use
`ngrok tcp` or `ngrok tls` instead.
### Usage
```sh theme={null}
ngrok http [address:port | port] [flags]
```
### Example
```sh theme={null}
# forward traffic from a randomly assigned URL to port 8080
ngrok http 8080
# forward to another host on the network with a host:port address
ngrok http servername.local:9000
# forward to an https server
ngrok http https://localhost:8443
# choose your endpoint URL instead of it being assigned
ngrok http 8080 --url htps://bar.ngrok.dev 80
# choose an endpoint URL on your own domain (requires a DNS CNAME)
ngrok http 3000 --url https://api.example.com
# add Traffic Policy config for auth, security, routing + more
ngrok http 80 --url https://example.ngrok.app --traffic-policy-file tp.yml
# load balance between endpoints (run in two terminals)
ngrok http 8081 --url https://your-api.ngrok.app --pooling-enabled
ngrok http 8080 --url https://your-api.ngrok.app --pooling-enabled
# forward to a file URL to serve files from a directory
ngrok http file:///var/log
```
### Flags
| Flag | Description |
| - | - |
| `--app-protocol` (deprecated) | use traffic policy instead |
| `--authtoken` | ngrok.com authtoken identifying a user |
| `--basic-auth` (deprecated) | use traffic policy instead |
| `--binding` | ingress binding for an agent endpoint |
| `--cidr-allow` (deprecated) | use traffic policy instead |
| `--cidr-deny` (deprecated) | use traffic policy instead |
| `--circuit-breaker` (deprecated) | use traffic policy instead |
| `--compression` (deprecated) | use traffic policy instead |
| `--description` | user editable description about this endpoint |
| `--domain` (deprecated) | use --url instead |
| `--host-header` (deprecated) | use traffic policy instead |
| `--hostname` (deprecated) | use --domain instead |
| `--inspect` | enable/disable http introspection (default true) |
| `--metadata` | metadata about this endpoint |
| `--mutual-tls-cas` (deprecated) | use traffic policy instead |
| `--name` | user supplied name for this endpoint |
| `--oauth` (deprecated) | use traffic policy instead |
| `--oauth-allow-domain` (deprecated) | use traffic policy instead |
| `--oauth-allow-email` (deprecated) | use traffic policy instead |
| `--oauth-client-id` (deprecated) | use traffic policy instead |
| `--oauth-client-secret` (deprecated) | use traffic policy instead |
| `--oauth-scope` (deprecated) | use traffic policy instead |
| `--oidc` (deprecated) | use traffic policy instead |
| `--oidc-client-id` (deprecated) | use traffic policy instead |
| `--oidc-client-secret` (deprecated) | use traffic policy instead |
| `--oidc-scope` (deprecated) | use traffic policy instead |
| `--policy-file` (deprecated) | use --traffic-policy-file instead |
| `--pooling-enabled` | whether this endpoint can be pooled |
| `--proxy-proto` (deprecated) | use --upstream-proxy-protocol instead |
| `--region` (deprecated) | ngrok automatically chooses the region with lowest latency |
| `--request-header-add` (deprecated) | use traffic policy instead |
| `--request-header-remove` (deprecated) | use traffic policy instead |
| `--response-header-add` (deprecated) | use traffic policy instead |
| `--response-header-remove` (deprecated) | use traffic policy instead |
| `--scheme` (deprecated) | use --url instead |
| `--subdomain` (deprecated) | use --domain instead |
| `--traffic-policy-file` | path to traffic policy configuration YAML or JSON file, e.g. './path/to/policy.yml' |
| `--traffic-policy-url` | URL to traffic policy configuration YAML or JSON file, e.g. '[https://example.com/policy.yml](https://example.com/policy.yml)' |
| `--ua-filter-allow` (deprecated) | use traffic policy instead |
| `--ua-filter-deny` (deprecated) | use traffic policy instead |
| `--upstream-protocol` (deprecated) | use traffic policy instead |
| `--upstream-proxy-protocol` | version of proxy proto to use with this tunnel, empty if not unused |
| `--upstream-tls-verify` | enables TLS verification of server TLS certificates |
| `--upstream-tls-verify-cas` | path to CA cert to use to verify server certs |
| `--url` | host endpoint on a URL |
| `--verify-webhook` (deprecated) | use traffic policy instead |
| `--verify-webhook-secret` (deprecated) | use traffic policy instead |
| `--websocket-tcp-converter` (deprecated) | use traffic policy instead |
| `--config` | path to config files; they are merged if multiple |
## ngrok service
The service command manages installation and execution of ngrok as an
operating system service on Windows, OS X and Linux systems.
The service command takes a single argument which must be 'start', 'stop',
'restart', 'install', or 'uninstall'.
When you choose 'install', you must specify the config flag which will
define where the installed ngrok service looks for its configuration file.
When the ngrok service runs, it has the same behavior as if it were invoked
from the command line with the command: "ngrok start --all".
For more information about running ngrok as a service, check out the [ngrok service section in the secure tunnels documentation](/docs/gateway/agent/service#running-ngrok-in-the-background)
### Usage
```sh theme={null}
ngrok service [flags]
```
### Example
```sh theme={null}
ngrok service install --config=C:\ngrok.yml
ngrok service start
ngrok service stop
```
### Flags
| Flag | Description |
| - | - |
| `--config` | path to config files; they are merged if multiple |
## ngrok start
start - start endpoints by name from the configuration file
### Usage
```sh theme={null}
ngrok start [flags]
```
### Example
```sh theme={null}
ngrok start dev # start tunnel named 'dev' in the configuration file
ngrok start web blog # start tunnels named 'web' and 'blog'
ngrok start --all # start all tunnels defined in the config file
```
### Flags
| Flag | Description |
| - | - |
| `--all` | start all endpoints or tunnels in the configuration file |
| `--authtoken` | ngrok.com authtoken identifying a user |
| `--none` | start running no endpoints or tunnels |
| `--region` (deprecated) | ngrok automatically chooses the region with lowest latency |
| `--config` | path to config files; they are merged if multiple |
## ngrok tcp
Starts a tunnel which forwards all TCP traffic on a public port to a local
address. This is extremely useful for exposing services that run non-HTTP
traffic (ssh, sip, rdp, game servers, etc).
A TCP tunnel binds a public address on the remote ngrok server. Any
services which require a stable public address should use the
\--url option. ngrok requires that you reserve a TCP tunnel
address for your account before you can use it.
TCP endpoints are only available on a free plan after [adding a valid payment method](https://dashboard.ngrok.com/settings#id-verification) to your account.
### Usage
```sh theme={null}
ngrok tcp [address:port | port] [flags]
```
### Example
```sh theme={null}
# forward a port to your local ssh server
ngrok tcp 22
# expose an RDP server on a specific public address that you reserved
ngrok tcp --url=1.tcp.ngrok.io:27210 3389
```
### Flags
| Flag | Description |
| - | - |
| `--authtoken` | ngrok.com authtoken identifying a user |
| `--binding` | ingress binding for an agent endpoint |
| `--cidr-allow` | reject connections that do not match the given CIDRs |
| `--cidr-deny` | reject connections that match the given CIDRs |
| `--description` | user editable description about this endpoint |
| `--metadata` | metadata about this endpoint |
| `--name` | user supplied name for this endpoint |
| `--policy-file` (deprecated) | use --traffic-policy-file instead |
| `--pooling-enabled` | whether this endpoint can be pooled |
| `--proxy-proto` (deprecated) | use --upstream-proxy-protocol instead |
| `--region` (deprecated) | ngrok automatically chooses the region with lowest latency |
| `--remote-addr` (deprecated) | use --url instead |
| `--traffic-policy-file` | path to traffic policy configuration YAML or JSON file, e.g. './path/to/policy.yml' |
| `--traffic-policy-url` | URL to traffic policy configuration YAML or JSON file, e.g. '[https://example.com/policy.yml](https://example.com/policy.yml)' |
| `--upstream-proxy-protocol` | version of proxy proto to use with this tunnel, empty if not unused |
| `--url` | host endpoint on a URL |
| `--config` | path to config files; they are merged if multiple |
## ngrok tls
tls - create a TLS endpoint and forward traffic from it to a local server
Starts a tunnel listening for TLS traffic on port 443
with a specific hostname. The TLS SNI (Server Name Indication)
extension field in the TLS connection is inspected to determine
which tunnel it matches.
The ngrok server does not terminate TLS connections forwarded with this
command. Any underlying protocol may be used. You may optionally specify a
TLS key/cert pair which will be used to terminate the traffic client-side
before it is forwarded. If not specified, the traffic will be forwarded
still encrypted.
Using this command is only recommended with the --url option. Other uses
will work, but will always result in certificate mismatch warnings.
### Usage
```sh theme={null}
ngrok tls [address:port | port] [flags]
```
### Example
```sh theme={null}
# forward TLS traffic for example.com to port 443 (requires CNAME)
ngrok tls --url=example.com 443
# forward TLS traffic on subdomain (mismatch certificate warning)
ngrok tls 1234
# terminate TLS traffic for t.co before forwarding
ngrok tls --url=t.co --crt=/path/to/t.co.crt --key=/path/to/t.co.key 443
```
### Flags
| Flag | Description |
| - | - |
| `--authtoken` | ngrok.com authtoken identifying a user |
| `--binding` | ingress bindings for an agent endpoint |
| `--cidr-allow` | reject connections that do not match the given CIDRs |
| `--cidr-deny` | reject connections that match the given CIDRs |
| `--crt` | path to a TLS certificate for TLS termination |
| `--description` | user editable description about this endpoint |
| `--domain` (deprecated) | use --url instead |
| `--hostname` (deprecated) | use --domain instead |
| `--key` | path to a TLS key for TLS termination |
| `--metadata` | metadata about this endpoint |
| `--mutual-tls-cas` | path to TLS certificate authority to verify client certs in mutual tls |
| `--name` | user supplied name for this endpoint |
| `--policy-file` (deprecated) | use --traffic-policy-file instead |
| `--pooling-enabled` | whether this endpoint can be pooled |
| `--proxy-proto` (deprecated) | use --upstream-proxy-protocol instead |
| `--region` (deprecated) | ngrok automatically chooses the region with lowest latency |
| `--subdomain` (deprecated) | use --domain instead |
| `--terminate-at` (deprecated) | this flag is deprecated and will be removed in a future release; use terminate-tls via Traffic Policy or agent\_tls\_termination via agent configuration instead |
| `--traffic-policy-file` | path to traffic policy configuration YAML or JSON file, e.g. './path/to/policy.yml' |
| `--traffic-policy-url` | URL to traffic policy configuration YAML or JSON file, e.g. '[https://example.com/policy.yml](https://example.com/policy.yml)' |
| `--upstream-proxy-protocol` | version of proxy proto to use with this tunnel, empty if not unused |
| `--upstream-tls-verify` | enables TLS verification of server TLS certificates |
| `--upstream-tls-verify-cas` | path to CA cert to use to verify server certs |
| `--url` | host endpoint on a URL |
| `--config` | path to config files; they are merged if multiple |
## ngrok update
This command checks the ngrok cloud service for a newer version of the ngrok
agent. If a newer version is available, it will download it and replace the
ngrok binary with the new version after cryptographically verifying the update
is signed by ngrok.
In order to update successfully, the ngrok binary must be in a directory
that is writable by your current user. If you placed ngrok in a system
path, you may need to run this with root or Administrator privileges.
Do not run this command if you installed ngrok with a package manager (i.e.
homebrew, chocolatey, apt, snap, etc). Instead, update ngrok by using your
package manager's update command.
### Usage
```sh theme={null}
ngrok update [flags]
```
### Example
```sh theme={null}
ngrok update # update ngrok to the latest stable version
ngrok update --channel=beta # update ngrok to the latest beta version
```
### Flags
| Flag | Description |
| - | - |
| `--channel` | update channel (stable, beta, unstable) |
| `--config` | path to config files; they are merged if multiple |
## ngrok version
print the version string
### Usage
```sh theme={null}
ngrok version [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--config` | path to config files; they are merged if multiple |
# ngrok Agent CLI API Commands
Source: https://ngrok.com/docs/gateway/agent/cli-api
With the ngrok agent CLI, you can use built-in commands to interact with the ngrok API.
For more information about the ngrok API and interfacing with it directly, see [the ngrok api page](/docs/api).
If you want to programmatically control the ngrok agent, the [Agent
SDKs](/docs/agent-sdks/) are usually a more flexible and powerful choice.
## ngrok api
The api command provides access to ngrok's API. You can use the API through
one of the api subcommmands.
All api subcommands require an API key. You can configure it either through
a command flag (--api-key) or add it in ngrok's configuration file (api\_key).
You can get the initial API key at [https://dashboard.ngrok.com/api-keys](https://dashboard.ngrok.com/api-keys).
Additional keys can be created through 'ngrok api api-keys create' subcommand.
### SubCommands
| Command | Description |
| - | - |
| [abuse-reports](#ngrok-api-abuse-reports) | Abuse Reports allow you to submit take-down requests for URLs hosted by ngrok that... |
| [agent-ingresses](#ngrok-api-agent-ingresses) | |
| [api-keys](#ngrok-api-api-keys) | API Keys are used to authenticate to the ngrok API ([https://ngrok](https://ngrok) |
| [application-sessions](#ngrok-api-application-sessions) | |
| [application-users](#ngrok-api-application-users) | |
| [backends](#ngrok-api-backends) | |
| [bot-users](#ngrok-api-bot-users) | |
| [certificate-authorities](#ngrok-api-certificate-authorities) | Certificate Authorities are x509 certificates that are used to sign other x509... |
| [credentials](#ngrok-api-credentials) | Tunnel Credentials are ngrok agent authtokens |
| [edge-modules](#ngrok-api-edge-modules) | |
| [edges](#ngrok-api-edges) | |
| [endpoint-configurations](#ngrok-api-endpoint-configurations) | Endpoint Configurations are a reusable group of modules that encapsulate how traffic... |
| [endpoints](#ngrok-api-endpoints) | Endpoints provides an API for querying the endpoint objects which define what tunnel... |
| [event-destinations](#ngrok-api-event-destinations) | |
| [event-sources](#ngrok-api-event-sources) | |
| [event-subscriptions](#ngrok-api-event-subscriptions) | |
| [ip-policies](#ngrok-api-ip-policies) | IP Policies are reusable groups of CIDR ranges with an allow or deny action |
| [ip-policy-rules](#ngrok-api-ip-policy-rules) | IP Policy Rules are the IPv4 or IPv6 CIDRs entries that make up an IP Policy. |
| [ip-restrictions](#ngrok-api-ip-restrictions) | An IP restriction is a restriction placed on the CIDRs that are allowed to initiate... |
| [kubernetes-operators](#ngrok-api-kubernetes-operators) | KubernetesOperators is used by the Kubernetes Operator to register and manage its own... |
| [networks](#ngrok-api-networks) | Networks provide private address space for an account. |
| [personal-access-tokens](#ngrok-api-personal-access-tokens) | Personal Access Tokens (PATs) are bearer credentials that authenticate the ngrok agent... |
| [pointcfg-module](#ngrok-api-pointcfg-module) | |
| [reserved-addrs](#ngrok-api-reserved-addrs) | Reserved Addresses are TCP addresses that can be used to listen for traffic |
| [reserved-domains](#ngrok-api-reserved-domains) | Reserved Domains are hostnames that you can listen for traffic on |
| [root](#ngrok-api-root) | |
| [secrets](#ngrok-api-secrets) | Secrets is an api service for securely storing and managing sensitive data such as... |
| [service-users](#ngrok-api-service-users) | |
| [ssh-certificate-authorities](#ngrok-api-ssh-certificate-authorities) | An SSH Certificate Authority is a pair of an SSH Certificate and its private key that... |
| [ssh-credentials](#ngrok-api-ssh-credentials) | SSH Credentials are SSH public keys that can be used to start SSH tunnels via the... |
| [ssh-host-certificates](#ngrok-api-ssh-host-certificates) | SSH Host Certificates along with the corresponding private key allows an SSH server to... |
| [ssh-user-certificates](#ngrok-api-ssh-user-certificates) | SSH User Certificates are presented by SSH clients when connecting to an SSH server to... |
| [tls-certificates](#ngrok-api-tls-certificates) | TLS Certificates are pairs of x509 certificates and their matching private key that... |
| [tunnel-sessions](#ngrok-api-tunnel-sessions) | Tunnel Sessions represent instances of ngrok agents or SSH reverse tunnel sessions... |
| [tunnels](#ngrok-api-tunnels) | Tunnels provide endpoints to access services exposed by a running ngrok agent tunnel... |
| [vaults](#ngrok-api-vaults) | Vaults is an api service for securely storing and managing sensitive data such as... |
### Flags
| Flag | Description |
| - | - |
| `--config` | path to config files; they are merged if multiple |
## ngrok api abuse-reports
Abuse Reports allow you to submit take-down requests for URLs hosted by
ngrok that violate ngrok's terms of service.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-abuse-reports-create) | Creates a new abuse report which will be... |
| [get](#ngrok-api-abuse-reports-get) | Get the detailed status of abuse report by ID. |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api abuse-reports create
Creates a new abuse report which will be reviewed by our system and abuse response team. This API is only available to authorized accounts. Contact [abuse@ngrok.com](mailto:abuse@ngrok.com) to request access
### Usage
```sh theme={null}
ngrok api abuse-reports create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--metadata` | arbitrary user-defined data about this abuse report. Optional, max 4096 bytes. |
| `--urls` | a list of URLs containing suspected abusive content |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api abuse-reports get
Get the detailed status of abuse report by ID.
### Usage
```sh theme={null}
ngrok api abuse-reports get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api agent-ingresses
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-agent-ingresses-create) | Create a new Agent Ingress |
| [delete](#ngrok-api-agent-ingresses-delete) | Delete an Agent Ingress by ID |
| [get](#ngrok-api-agent-ingresses-get) | Get the details of an Agent Ingress by ID. |
| [list](#ngrok-api-agent-ingresses-list) | List all Agent Ingresses owned by this account |
| [update](#ngrok-api-agent-ingresses-update) | Update attributes of an Agent Ingress by ID. |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api agent-ingresses create
Create a new Agent Ingress. The ngrok agent can be configured to connect to ngrok via the new set of addresses on the returned Agent Ingress.
### Usage
```sh theme={null}
ngrok api agent-ingresses create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--certificate-management-policy.authority` | certificate authority to request certificates from. The only supported value is letsencrypt. |
| `--certificate-management-policy.private-key-type` | type of private key to use when requesting certificates. Defaults to rsa, can be either rsa or ecdsa. |
| `--description` | human-readable description of the use of this Agent Ingress. optional, max 255 bytes. |
| `--domain` | the domain that you own to be used as the base domain name to generate regional agent ingress domains. |
| `--metadata` | arbitrary user-defined machine-readable data of this Agent Ingress. optional, max 4096 bytes |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api agent-ingresses delete
Delete an Agent Ingress by ID
### Usage
```sh theme={null}
ngrok api agent-ingresses delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api agent-ingresses get
Get the details of an Agent Ingress by ID.
### Usage
```sh theme={null}
ngrok api agent-ingresses get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api agent-ingresses list
List all Agent Ingresses owned by this account
### Usage
```sh theme={null}
ngrok api agent-ingresses list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | Expects a resource ID as its input. Returns earlier entries in the result set, sorted by ID. |
| `--filter` | A CEL expression to filter the list results. Supports logical and comparison operators to match on fields such as id, metadata, created\_at, and more. See ngrok API Filtering for syntax and field details: [https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering) ([https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering)). |
| `--limit` | Constrains the number of results in the dataset. See the API Overview ([https://ngrok.com/docs/api/index#pagination](https://ngrok.com/docs/api/index#pagination)) for details. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api agent-ingresses update
Update attributes of an Agent Ingress by ID.
### Usage
```sh theme={null}
ngrok api agent-ingresses update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--certificate-management-policy.authority` | certificate authority to request certificates from. The only supported value is letsencrypt. |
| `--certificate-management-policy.private-key-type` | type of private key to use when requesting certificates. Defaults to rsa, can be either rsa or ecdsa. |
| `--description` | human-readable description of the use of this Agent Ingress. optional, max 255 bytes. |
| `--metadata` | arbitrary user-defined machine-readable data of this Agent Ingress. optional, max 4096 bytes |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api api-keys
API Keys are used to authenticate to the ngrok
API ([https://ngrok.com/docs/api#authentication](https://ngrok.com/docs/api#authentication)). You may use the API itself
to provision and manage API Keys but you'll need to provision your first API
key from the API Keys page ([https://dashboard.ngrok.com/api-keys](https://dashboard.ngrok.com/api-keys)) on your
ngrok.com dashboard.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-api-keys-create) | Create a new API key |
| [delete](#ngrok-api-api-keys-delete) | Delete an API key by ID |
| [get](#ngrok-api-api-keys-get) | Get the details of an API key by ID. |
| [list](#ngrok-api-api-keys-list) | List all API keys owned by this account |
| [update](#ngrok-api-api-keys-update) | Update attributes of an API key by ID. |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api api-keys create
Create a new API key. The generated API key can be used to authenticate to the ngrok API.
### Usage
```sh theme={null}
ngrok api api-keys create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of what uses the API key to authenticate. optional, max 255 bytes. |
| `--metadata` | arbitrary user-defined data of this API key. optional, max 4096 bytes |
| `--owner-email` | If supplied at credential creation, ownership will be assigned to the specified User. Only admins may specify an owner other than themselves. Both owner\_id and owner\_email may not be specified. |
| `--owner-id` | If supplied at credential creation, ownership will be assigned to the specified User or Bot. Only admins may specify an owner other than themselves. Defaults to the authenticated User or Bot. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api api-keys delete
Delete an API key by ID
### Usage
```sh theme={null}
ngrok api api-keys delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api api-keys get
Get the details of an API key by ID.
### Usage
```sh theme={null}
ngrok api api-keys get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api api-keys list
List all API keys owned by this account
### Usage
```sh theme={null}
ngrok api api-keys list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | Expects a resource ID as its input. Returns earlier entries in the result set, sorted by ID. |
| `--filter` | A CEL expression to filter the list results. Supports logical and comparison operators to match on fields such as id, metadata, created\_at, and more. See ngrok API Filtering for syntax and field details: [https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering) ([https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering)). |
| `--limit` | Constrains the number of results in the dataset. See the API Overview ([https://ngrok.com/docs/api/index#pagination](https://ngrok.com/docs/api/index#pagination)) for details. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api api-keys update
Update attributes of an API key by ID.
### Usage
```sh theme={null}
ngrok api api-keys update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of what uses the API key to authenticate. optional, max 255 bytes. |
| `--metadata` | arbitrary user-defined data of this API key. optional, max 4096 bytes |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api application-sessions
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-application-sessions-delete) | Delete an application session by ID. |
| [get](#ngrok-api-application-sessions-get) | Get an application session by ID. |
| [list](#ngrok-api-application-sessions-list) | List all application sessions for this account. |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api application-sessions delete
Delete an application session by ID.
### Usage
```sh theme={null}
ngrok api application-sessions delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api application-sessions get
Get an application session by ID.
### Usage
```sh theme={null}
ngrok api application-sessions get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api application-sessions list
List all application sessions for this account.
### Usage
```sh theme={null}
ngrok api application-sessions list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api application-users
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-application-users-delete) | Delete an application user by ID. |
| [get](#ngrok-api-application-users-get) | Get an application user by ID. |
| [list](#ngrok-api-application-users-list) | List all application users for this account. |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api application-users delete
Delete an application user by ID.
### Usage
```sh theme={null}
ngrok api application-users delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api application-users get
Get an application user by ID.
### Usage
```sh theme={null}
ngrok api application-users get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api application-users list
List all application users for this account.
### Usage
```sh theme={null}
ngrok api application-users list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends
### SubCommands
| Command | Description |
| - | - |
| [failover](#ngrok-api-backends-failover) | A Failover backend defines failover behavior within a list of referenced backends |
| [http-response](#ngrok-api-backends-http-response) | |
| [static-address](#ngrok-api-backends-static-address) | A static backend sends traffic to a TCP address (hostname and port) that is reachable... |
| [tunnel-group](#ngrok-api-backends-tunnel-group) | A Tunnel Group Backend balances traffic among all online tunnels that match a label... |
| [weighted](#ngrok-api-backends-weighted) | A Weighted Backend balances traffic among the referenced backends |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends failover
A Failover backend defines failover behavior within a list of referenced
backends. Traffic is sent to the first backend in the list. If that backend
is offline or no connection can be established, ngrok attempts to connect to
the next backend in the list until one is successful.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-backends-failover-create) | Create a new Failover backend |
| [delete](#ngrok-api-backends-failover-delete) | Delete a Failover backend by ID. |
| [get](#ngrok-api-backends-failover-get) | Get detailed information about a Failover... |
| [list](#ngrok-api-backends-failover-list) | List all Failover backends on this account |
| [update](#ngrok-api-backends-failover-update) | Update Failover backend by ID |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends failover create
Create a new Failover backend
### Usage
```sh theme={null}
ngrok api backends failover create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backends` | the ids of the child backends in order |
| `--description` | human-readable description of this backend. Optional |
| `--metadata` | arbitrary user-defined machine-readable data of this backend. Optional |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends failover delete
Delete a Failover backend by ID.
### Usage
```sh theme={null}
ngrok api backends failover delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends failover get
Get detailed information about a Failover backend by ID
### Usage
```sh theme={null}
ngrok api backends failover get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends failover list
List all Failover backends on this account
### Usage
```sh theme={null}
ngrok api backends failover list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends failover update
Update Failover backend by ID
### Usage
```sh theme={null}
ngrok api backends failover update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backends` | the ids of the child backends in order |
| `--description` | human-readable description of this backend. Optional |
| `--metadata` | arbitrary user-defined machine-readable data of this backend. Optional |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends http-response
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-backends-http-response-create) | |
| [delete](#ngrok-api-backends-http-response-delete) | |
| [get](#ngrok-api-backends-http-response-get) | |
| [list](#ngrok-api-backends-http-response-list) | |
| [update](#ngrok-api-backends-http-response-update) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends http-response create
### Usage
```sh theme={null}
ngrok api backends http-response create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--body` | body to return as fixed content |
| `--description` | human-readable description of this backend. Optional |
| `--headers` | headers to return |
| `--metadata` | arbitrary user-defined machine-readable data of this backend. Optional |
| `--status-code` | status code to return |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends http-response delete
### Usage
```sh theme={null}
ngrok api backends http-response delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends http-response get
### Usage
```sh theme={null}
ngrok api backends http-response get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends http-response list
### Usage
```sh theme={null}
ngrok api backends http-response list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends http-response update
### Usage
```sh theme={null}
ngrok api backends http-response update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--body` | body to return as fixed content |
| `--description` | human-readable description of this backend. Optional |
| `--headers` | headers to return |
| `--metadata` | arbitrary user-defined machine-readable data of this backend. Optional |
| `--status-code` | status code to return |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends static-address
A static backend sends traffic to a TCP address (hostname and port) that
is reachable on the public internet.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-backends-static-address-create) | Create a new static backend |
| [delete](#ngrok-api-backends-static-address-delete) | Delete a static backend by ID. |
| [get](#ngrok-api-backends-static-address-get) | Get detailed information about a static... |
| [list](#ngrok-api-backends-static-address-list) | List all static backends on this account |
| [update](#ngrok-api-backends-static-address-update) | Update static backend by ID |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends static-address create
Create a new static backend
### Usage
```sh theme={null}
ngrok api backends static-address create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--address` | the address to forward to |
| `--description` | human-readable description of this backend. Optional |
| `--metadata` | arbitrary user-defined machine-readable data of this backend. Optional |
| `--tls.enabled` | if TLS is checked |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends static-address delete
Delete a static backend by ID.
### Usage
```sh theme={null}
ngrok api backends static-address delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends static-address get
Get detailed information about a static backend by ID
### Usage
```sh theme={null}
ngrok api backends static-address get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends static-address list
List all static backends on this account
### Usage
```sh theme={null}
ngrok api backends static-address list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends static-address update
Update static backend by ID
### Usage
```sh theme={null}
ngrok api backends static-address update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--address` | the address to forward to |
| `--description` | human-readable description of this backend. Optional |
| `--metadata` | arbitrary user-defined machine-readable data of this backend. Optional |
| `--tls.enabled` | if TLS is checked |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends tunnel-group
A Tunnel Group Backend balances traffic among all online tunnels that match
a label selector.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-backends-tunnel-group-create) | Create a new TunnelGroup backend |
| [delete](#ngrok-api-backends-tunnel-group-delete) | Delete a TunnelGroup backend by ID. |
| [get](#ngrok-api-backends-tunnel-group-get) | Get detailed information about a TunnelGroup... |
| [list](#ngrok-api-backends-tunnel-group-list) | List all TunnelGroup backends on this account |
| [update](#ngrok-api-backends-tunnel-group-update) | Update TunnelGroup backend by ID |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends tunnel-group create
Create a new TunnelGroup backend
### Usage
```sh theme={null}
ngrok api backends tunnel-group create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of this backend. Optional |
| `--labels` | labels to watch for tunnels on, e.g. app->foo, dc->bar |
| `--metadata` | arbitrary user-defined machine-readable data of this backend. Optional |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends tunnel-group delete
Delete a TunnelGroup backend by ID.
### Usage
```sh theme={null}
ngrok api backends tunnel-group delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends tunnel-group get
Get detailed information about a TunnelGroup backend by ID
### Usage
```sh theme={null}
ngrok api backends tunnel-group get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends tunnel-group list
List all TunnelGroup backends on this account
### Usage
```sh theme={null}
ngrok api backends tunnel-group list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends tunnel-group update
Update TunnelGroup backend by ID
### Usage
```sh theme={null}
ngrok api backends tunnel-group update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of this backend. Optional |
| `--labels` | labels to watch for tunnels on, e.g. app->foo, dc->bar |
| `--metadata` | arbitrary user-defined machine-readable data of this backend. Optional |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends weighted
A Weighted Backend balances traffic among the referenced backends. Traffic
is assigned proportionally to each based on its weight. The percentage of
traffic is calculated by dividing a backend's weight by the sum of all
weights.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-backends-weighted-create) | Create a new Weighted backend |
| [delete](#ngrok-api-backends-weighted-delete) | Delete a Weighted backend by ID. |
| [get](#ngrok-api-backends-weighted-get) | Get detailed information about a Weighted... |
| [list](#ngrok-api-backends-weighted-list) | List all Weighted backends on this account |
| [update](#ngrok-api-backends-weighted-update) | Update Weighted backend by ID |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends weighted create
Create a new Weighted backend
### Usage
```sh theme={null}
ngrok api backends weighted create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backends` | the ids of the child backends to their weights \[0-10000] |
| `--description` | human-readable description of this backend. Optional |
| `--metadata` | arbitrary user-defined machine-readable data of this backend. Optional |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends weighted delete
Delete a Weighted backend by ID.
### Usage
```sh theme={null}
ngrok api backends weighted delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends weighted get
Get detailed information about a Weighted backend by ID
### Usage
```sh theme={null}
ngrok api backends weighted get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends weighted list
List all Weighted backends on this account
### Usage
```sh theme={null}
ngrok api backends weighted list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api backends weighted update
Update Weighted backend by ID
### Usage
```sh theme={null}
ngrok api backends weighted update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backends` | the ids of the child backends to their weights \[0-10000] |
| `--description` | human-readable description of this backend. Optional |
| `--metadata` | arbitrary user-defined machine-readable data of this backend. Optional |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api bot-users
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-bot-users-create) | Create a new bot user |
| [delete](#ngrok-api-bot-users-delete) | Delete a bot user by ID |
| [get](#ngrok-api-bot-users-get) | Get the details of a Bot User by ID. |
| [list](#ngrok-api-bot-users-list) | List all bot users in this account. |
| [update](#ngrok-api-bot-users-update) | Update attributes of a bot user by ID. |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api bot-users create
Create a new bot user
### Usage
```sh theme={null}
ngrok api bot-users create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--active` | whether or not the service user is active |
| `--name` | human-readable name used to identify the service user |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api bot-users delete
Delete a bot user by ID
### Usage
```sh theme={null}
ngrok api bot-users delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api bot-users get
Get the details of a Bot User by ID.
### Usage
```sh theme={null}
ngrok api bot-users get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api bot-users list
List all bot users in this account.
### Usage
```sh theme={null}
ngrok api bot-users list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api bot-users update
Update attributes of a bot user by ID.
### Usage
```sh theme={null}
ngrok api bot-users update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--active` | whether or not the service user is active |
| `--name` | human-readable name used to identify the service user |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api certificate-authorities
Certificate Authorities are x509 certificates that are used to sign other
x509 certificates. Attach a Certificate Authority to the Mutual TLS module
to verify that the TLS certificate presented by a client has been signed by
this CA. Certificate Authorities are used only for mTLS validation only and
thus a private key is not included in the resource.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-certificate-authorities-create) | Upload a new Certificate Authority |
| [delete](#ngrok-api-certificate-authorities-delete) | Delete a Certificate Authority |
| [get](#ngrok-api-certificate-authorities-get) | Get detailed information about a certificate... |
| [list](#ngrok-api-certificate-authorities-list) | List all Certificate Authority on this account |
| [update](#ngrok-api-certificate-authorities-update) | Update attributes of a Certificate Authority... |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api certificate-authorities create
Upload a new Certificate Authority
### Usage
```sh theme={null}
ngrok api certificate-authorities create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--ca-pem` | raw PEM of the Certificate Authority |
| `--description` | human-readable description of this Certificate Authority. optional, max 255 bytes. |
| `--metadata` | arbitrary user-defined machine-readable data of this Certificate Authority. optional, max 4096 bytes. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api certificate-authorities delete
Delete a Certificate Authority
### Usage
```sh theme={null}
ngrok api certificate-authorities delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api certificate-authorities get
Get detailed information about a certificate authority
### Usage
```sh theme={null}
ngrok api certificate-authorities get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api certificate-authorities list
List all Certificate Authority on this account
### Usage
```sh theme={null}
ngrok api certificate-authorities list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | Expects a resource ID as its input. Returns earlier entries in the result set, sorted by ID. |
| `--filter` | A CEL expression to filter the list results. Supports logical and comparison operators to match on fields such as id, metadata, created\_at, and more. See ngrok API Filtering for syntax and field details: [https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering) ([https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering)). |
| `--limit` | Constrains the number of results in the dataset. See the API Overview ([https://ngrok.com/docs/api/index#pagination](https://ngrok.com/docs/api/index#pagination)) for details. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api certificate-authorities update
Update attributes of a Certificate Authority by ID
### Usage
```sh theme={null}
ngrok api certificate-authorities update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of this Certificate Authority. optional, max 255 bytes. |
| `--metadata` | arbitrary user-defined machine-readable data of this Certificate Authority. optional, max 4096 bytes. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api credentials
Tunnel Credentials are ngrok agent authtokens. They authorize the ngrok
agent to connect the ngrok service as your account. They are installed with
the ngrok config add-authtoken command or by specifying it in the ngrok.yml
configuration file with the authtoken property.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-credentials-create) | Create a new tunnel authtoken credential |
| [delete](#ngrok-api-credentials-delete) | Delete a tunnel authtoken credential by ID |
| [get](#ngrok-api-credentials-get) | Get detailed information about a tunnel... |
| [list](#ngrok-api-credentials-list) | List all tunnel authtoken credentials on this... |
| [update](#ngrok-api-credentials-update) | Update attributes of an tunnel authtoken... |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api credentials create
Create a new tunnel authtoken credential. This authtoken credential can be used to start a new tunnel session. The response to this API call is the only time the generated token is available. If you need it for future use, you must save it securely yourself.
### Usage
```sh theme={null}
ngrok api credentials create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--acl` | optional list of ACL rules. If unspecified, the credential will have no restrictions. The only allowed ACL rule at this time is the bind rule. The bind rule allows the caller to restrict what domains, addresses, and labels the token is allowed to bind. For example, to allow the token to open a tunnel on example.ngrok.io your ACL would include the rule bind:example.ngrok.io. Bind rules for domains may specify a leading wildcard to match multiple domains with a common suffix. For example, you may specify a rule of bind:*.example.com which will allow x.example.com, y.example.com, *.example.com, etc. Bind rules for labels may specify a wildcard key and/or value to match multiple labels. For example, you may specify a rule of bind:*=example which will allow x=example, y=example, etc. A rule of '*' is equivalent to no acl at all and will explicitly permit all actions. |
| `--description` | human-readable description of who or what will use the credential to authenticate. Optional, max 255 bytes. |
| `--metadata` | arbitrary user-defined machine-readable data of this credential. Optional, max 4096 bytes. |
| `--owner-email` | If supplied at credential creation, ownership will be assigned to the specified User. Only admins may specify an owner other than themselves. Only one of owner\_id, owner\_email, or scim\_user\_id may be specified. specified. |
| `--owner-id` | If supplied at credential creation, ownership will be assigned to the specified User or Service User. Only admins may specify an owner other than themselves. Defaults to the authenticated User or Service User. Accepts one of: User ID, User email, or SCIM User ID. |
| `--precomputed-token` | Only authorized accounts may supply a pre-computed token that will be associated with the created credentials. |
| `--scim-user-id` | If supplied at credential creation, ownership will be assigned to the specified SCIM User. Only admins may specify an owner other than themselves. Only one of owner\_id, owner\_email, or scim\_user\_id may be specified. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api credentials delete
Delete a tunnel authtoken credential by ID
### Usage
```sh theme={null}
ngrok api credentials delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api credentials get
Get detailed information about a tunnel authtoken credential
### Usage
```sh theme={null}
ngrok api credentials get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api credentials list
List all tunnel authtoken credentials on this account
### Usage
```sh theme={null}
ngrok api credentials list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | Expects a resource ID as its input. Returns earlier entries in the result set, sorted by ID. |
| `--filter` | A CEL expression to filter the list results. Supports logical and comparison operators to match on fields such as id, metadata, created\_at, and more. See ngrok API Filtering for syntax and field details: [https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering) ([https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering)). |
| `--limit` | Constrains the number of results in the dataset. See the API Overview ([https://ngrok.com/docs/api/index#pagination](https://ngrok.com/docs/api/index#pagination)) for details. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api credentials update
Update attributes of an tunnel authtoken credential by ID
### Usage
```sh theme={null}
ngrok api credentials update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--acl` | optional list of ACL rules. If unspecified, the credential will have no restrictions. The only allowed ACL rule at this time is the bind rule. The bind rule allows the caller to restrict what domains, addresses, and labels the token is allowed to bind. For example, to allow the token to open a tunnel on example.ngrok.io your ACL would include the rule bind:example.ngrok.io. Bind rules for domains may specify a leading wildcard to match multiple domains with a common suffix. For example, you may specify a rule of bind:*.example.com which will allow x.example.com, y.example.com, *.example.com, etc. Bind rules for labels may specify a wildcard key and/or value to match multiple labels. For example, you may specify a rule of bind:*=example which will allow x=example, y=example, etc. A rule of '*' is equivalent to no acl at all and will explicitly permit all actions. |
| `--description` | human-readable description of who or what will use the credential to authenticate. Optional, max 255 bytes. |
| `--metadata` | arbitrary user-defined machine-readable data of this credential. Optional, max 4096 bytes. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules
### SubCommands
| Command | Description |
| - | - |
| [https-edge-mutual-tls](#ngrok-api-edge-modules-https-edge-mutual-tls) | |
| [https-edge-route-backend](#ngrok-api-edge-modules-https-edge-route-backend) | |
| [https-edge-route-circuit-breaker](#ngrok-api-edge-modules-https-edge-route-circuit-breaker) | |
| [https-edge-route-compression](#ngrok-api-edge-modules-https-edge-route-compression) | |
| [https-edge-route-ip-restriction](#ngrok-api-edge-modules-https-edge-route-ip-restriction) | |
| [https-edge-route-oauth](#ngrok-api-edge-modules-https-edge-route-oauth) | |
| [https-edge-route-oidc](#ngrok-api-edge-modules-https-edge-route-oidc) | |
| [https-edge-route-request-headers](#ngrok-api-edge-modules-https-edge-route-request-headers) | |
| [https-edge-route-response-headers](#ngrok-api-edge-modules-https-edge-route-response-headers) | |
| [https-edge-route-saml](#ngrok-api-edge-modules-https-edge-route-saml) | |
| [https-edge-route-traffic-policy](#ngrok-api-edge-modules-https-edge-route-traffic-policy) | |
| [https-edge-route-user-agent-filter](#ngrok-api-edge-modules-https-edge-route-user-agent-filter) | |
| [https-edge-route-webhook-verification](#ngrok-api-edge-modules-https-edge-route-webhook-verification) | |
| [https-edge-route-websocket-tcp-converter](#ngrok-api-edge-modules-https-edge-route-websocket-tcp-converter) | |
| [https-edge-tls-termination](#ngrok-api-edge-modules-https-edge-tls-termination) | |
| [tcp-edge-backend](#ngrok-api-edge-modules-tcp-edge-backend) | |
| [tcp-edge-ip-restriction](#ngrok-api-edge-modules-tcp-edge-ip-restriction) | |
| [tcp-edge-traffic-policy](#ngrok-api-edge-modules-tcp-edge-traffic-policy) | |
| [tls-edge-backend](#ngrok-api-edge-modules-tls-edge-backend) | |
| [tls-edge-ip-restriction](#ngrok-api-edge-modules-tls-edge-ip-restriction) | |
| [tls-edge-mutual-tls](#ngrok-api-edge-modules-tls-edge-mutual-tls) | |
| [tls-edge-tls-termination](#ngrok-api-edge-modules-tls-edge-tls-termination) | |
| [tls-edge-traffic-policy](#ngrok-api-edge-modules-tls-edge-traffic-policy) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-mutual-tls
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-mutual-tls-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-mutual-tls-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-mutual-tls-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-mutual-tls delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-mutual-tls delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-mutual-tls get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-mutual-tls get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-mutual-tls replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-mutual-tls replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.certificate-authority-ids` | list of certificate authorities that will be used to validate the TLS client certificate presented by the initiator of the TLS connection |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-backend
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-backend-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-backend-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-backend-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-backend delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-backend delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-backend get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-backend get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-backend replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-backend replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.backend-id` | backend to be used to back this endpoint |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-circuit-breaker
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-circuit-breaker-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-circuit-breaker-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-circuit-breaker-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-circuit-breaker delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-circuit-breaker delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-circuit-breaker get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-circuit-breaker get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-circuit-breaker replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-circuit-breaker replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.error-threshold-percentage` | Error threshold percentage should be between 0 - 1.0, not 0-100.0 |
| `--module.num-buckets` | Integer number of buckets into which metrics are retained. Max 128. |
| `--module.rolling-window` | Integer number of seconds in the statistical rolling window that metrics are retained for. |
| `--module.tripped-duration` | Integer number of seconds after which the circuit is tripped to wait before re-evaluating upstream health |
| `--module.volume-threshold` | Integer number of requests in a rolling window that will trip the circuit. Helpful if traffic volume is low. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-compression
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-compression-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-compression-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-compression-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-compression delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-compression delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-compression get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-compression get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-compression replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-compression replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-ip-restriction
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-ip-restriction-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-ip-restriction-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-ip-restriction-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-ip-restriction delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-ip-restriction delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-ip-restriction get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-ip-restriction get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-ip-restriction replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-ip-restriction replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-oauth
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-oauth-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-oauth-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-oauth-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-oauth delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-oauth delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-oauth get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-oauth get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-oauth replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-oauth replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.auth-check-interval` | Integer number of seconds after which ngrok guarantees it will refresh user state from the identity provider and recheck whether the user is still authorized to access the endpoint. This is the preferred tunable to use to enforce a minimum amount of time after which a revoked user will no longer be able to access the resource. |
| `--module.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--module.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--module.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--module.provider.amazon.client-id` | |
| `--module.provider.amazon.client-secret` | |
| `--module.provider.amazon.email-addresses` | |
| `--module.provider.amazon.email-domains` | |
| `--module.provider.amazon.scopes` | |
| `--module.provider.facebook.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--module.provider.facebook.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--module.provider.facebook.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--module.provider.facebook.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--module.provider.facebook.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--module.provider.github.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--module.provider.github.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--module.provider.github.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--module.provider.github.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--module.provider.github.organizations` | a list of github org identifiers. users who are members of any of the listed organizations will be allowed access. identifiers should be the organization's 'slug' |
| `--module.provider.github.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--module.provider.github.teams` | a list of github teams identifiers. users will be allowed access to the endpoint if they are a member of any of these teams. identifiers should be in the 'slug' format qualified with the org name, e.g. org-name/team-name |
| `--module.provider.gitlab.client-id` | |
| `--module.provider.gitlab.client-secret` | |
| `--module.provider.gitlab.email-addresses` | |
| `--module.provider.gitlab.email-domains` | |
| `--module.provider.gitlab.scopes` | |
| `--module.provider.google.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--module.provider.google.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--module.provider.google.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--module.provider.google.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--module.provider.google.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--module.provider.linkedin.client-id` | |
| `--module.provider.linkedin.client-secret` | |
| `--module.provider.linkedin.email-addresses` | |
| `--module.provider.linkedin.email-domains` | |
| `--module.provider.linkedin.scopes` | |
| `--module.provider.microsoft.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--module.provider.microsoft.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--module.provider.microsoft.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--module.provider.microsoft.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--module.provider.microsoft.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--module.provider.twitch.client-id` | |
| `--module.provider.twitch.client-secret` | |
| `--module.provider.twitch.email-addresses` | |
| `--module.provider.twitch.email-domains` | |
| `--module.provider.twitch.scopes` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-oidc
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-oidc-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-oidc-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-oidc-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-oidc delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-oidc delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-oidc get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-oidc get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-oidc replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-oidc replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.client-id` | The OIDC app's client ID and OIDC audience. |
| `--module.client-secret` | The OIDC app's client secret. |
| `--module.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--module.issuer` | URL of the OIDC "OpenID provider". This is the base URL used for discovery. |
| `--module.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--module.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--module.scopes` | The set of scopes to request from the OIDC identity provider. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-request-headers
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-request-headers-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-request-headers-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-request-headers-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-request-headers delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-request-headers delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-request-headers get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-request-headers get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-request-headers replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-request-headers replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.add` | a map of header key to header value that will be injected into the HTTP Request before being sent to the upstream application server |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.remove` | a list of header names that will be removed from the HTTP Request before being sent to the upstream application server |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-response-headers
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-response-headers-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-response-headers-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-response-headers-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-response-headers delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-response-headers delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-response-headers get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-response-headers get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-response-headers replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-response-headers replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.add` | a map of header key to header value that will be injected into the HTTP Response returned to the HTTP client |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.remove` | a list of header names that will be removed from the HTTP Response returned to the HTTP client |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-saml
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-saml-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-saml-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-saml-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-saml delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-saml delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-saml get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-saml get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-saml replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-saml replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.allow-idp-initiated` | If true, the IdP may initiate a login directly (e.g. the user does not need to visit the endpoint first and then be redirected). The IdP should set the RelayState parameter to the target URL of the resource they want the user to be redirected to after the SAML login assertion has been processed. |
| `--module.authorized-groups` | If present, only users who are a member of one of the listed groups may access the target endpoint. |
| `--module.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.force-authn` | If true, indicates that whenever we redirect a user to the IdP for authentication that the IdP must prompt the user for authentication credentials even if the user already has a valid session with the IdP. |
| `--module.idp-metadata` | The full XML IdP EntityDescriptor. Your IdP may provide this to you as a a file to download or as a URL. |
| `--module.idp-metadata-url` | The IdP's metadata URL which returns the XML IdP EntityDescriptor. The IdP's metadata URL specifies how to connect to the IdP as well as its public key which is then used to validate the signature on incoming SAML assertions to the ACS endpoint. |
| `--module.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--module.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--module.nameid-format` | Defines the name identifier format the SP expects the IdP to use in its assertions to identify subjects. If unspecified, a default value of urn:oasis:names:tc:SAML:2.0:nameid-format:persistent will be used. A subset of the allowed values enumerated by the SAML specification are supported. |
| `--module.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-traffic-policy
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-traffic-policy-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-traffic-policy-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-traffic-policy-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-traffic-policy delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-traffic-policy delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-traffic-policy get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-traffic-policy get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-traffic-policy replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-traffic-policy replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.value` | the traffic policy that should be applied to the traffic on your endpoint. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-user-agent-filter
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-user-agent-filter-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-user-agent-filter-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-user-agent-filter-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-user-agent-filter delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-user-agent-filter delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-user-agent-filter get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-user-agent-filter get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-user-agent-filter replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-user-agent-filter replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.allow` | |
| `--module.deny` | |
| `--module.enabled` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-webhook-verification
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-webhook-verification-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-webhook-verification-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-webhook-verification-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-webhook-verification delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-webhook-verification delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-webhook-verification get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-webhook-verification get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-webhook-verification replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-webhook-verification replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.provider` | a string indicating which webhook provider will be sending webhooks to this endpoint. Value must be one of the supported providers defined at [https://ngrok.com/docs/cloud-edge/modules/webhook-verification](https://ngrok.com/docs/cloud-edge/modules/webhook-verification) ([https://ngrok.com/docs/cloud-edge/modules/webhook-verification](https://ngrok.com/docs/cloud-edge/modules/webhook-verification)) |
| `--module.secret` | a string secret used to validate requests from the given provider. All providers except AWS SNS require a secret |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-websocket-tcp-converter
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-route-websocket-tcp-converter-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-route-websocket-tcp-converter-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-route-websocket-tcp-converter-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-websocket-tcp-converter delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-websocket-tcp-converter delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-websocket-tcp-converter get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-websocket-tcp-converter get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-route-websocket-tcp-converter replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-route-websocket-tcp-converter replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-tls-termination
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-https-edge-tls-termination-delete) | |
| [get](#ngrok-api-edge-modules-https-edge-tls-termination-get) | |
| [replace](#ngrok-api-edge-modules-https-edge-tls-termination-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-tls-termination delete
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-tls-termination delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-tls-termination get
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-tls-termination get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules https-edge-tls-termination replace
### Usage
```sh theme={null}
ngrok api edge-modules https-edge-tls-termination replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.min-version` | The minimum TLS version used for termination and advertised to the client during the TLS handshake. if unspecified, ngrok will choose an industry-safe default. This value must be null if terminate\_at is set to upstream. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-backend
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-tcp-edge-backend-delete) | |
| [get](#ngrok-api-edge-modules-tcp-edge-backend-get) | |
| [replace](#ngrok-api-edge-modules-tcp-edge-backend-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-backend delete
### Usage
```sh theme={null}
ngrok api edge-modules tcp-edge-backend delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-backend get
### Usage
```sh theme={null}
ngrok api edge-modules tcp-edge-backend get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-backend replace
### Usage
```sh theme={null}
ngrok api edge-modules tcp-edge-backend replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.backend-id` | backend to be used to back this endpoint |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-ip-restriction
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-tcp-edge-ip-restriction-delete) | |
| [get](#ngrok-api-edge-modules-tcp-edge-ip-restriction-get) | |
| [replace](#ngrok-api-edge-modules-tcp-edge-ip-restriction-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-ip-restriction delete
### Usage
```sh theme={null}
ngrok api edge-modules tcp-edge-ip-restriction delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-ip-restriction get
### Usage
```sh theme={null}
ngrok api edge-modules tcp-edge-ip-restriction get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-ip-restriction replace
### Usage
```sh theme={null}
ngrok api edge-modules tcp-edge-ip-restriction replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-traffic-policy
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-tcp-edge-traffic-policy-delete) | |
| [get](#ngrok-api-edge-modules-tcp-edge-traffic-policy-get) | |
| [replace](#ngrok-api-edge-modules-tcp-edge-traffic-policy-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-traffic-policy delete
### Usage
```sh theme={null}
ngrok api edge-modules tcp-edge-traffic-policy delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-traffic-policy get
### Usage
```sh theme={null}
ngrok api edge-modules tcp-edge-traffic-policy get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tcp-edge-traffic-policy replace
### Usage
```sh theme={null}
ngrok api edge-modules tcp-edge-traffic-policy replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.value` | the traffic policy that should be applied to the traffic on your endpoint. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-backend
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-tls-edge-backend-delete) | |
| [get](#ngrok-api-edge-modules-tls-edge-backend-get) | |
| [replace](#ngrok-api-edge-modules-tls-edge-backend-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-backend delete
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-backend delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-backend get
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-backend get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-backend replace
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-backend replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.backend-id` | backend to be used to back this endpoint |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-ip-restriction
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-tls-edge-ip-restriction-delete) | |
| [get](#ngrok-api-edge-modules-tls-edge-ip-restriction-get) | |
| [replace](#ngrok-api-edge-modules-tls-edge-ip-restriction-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-ip-restriction delete
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-ip-restriction delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-ip-restriction get
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-ip-restriction get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-ip-restriction replace
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-ip-restriction replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-mutual-tls
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-tls-edge-mutual-tls-delete) | |
| [get](#ngrok-api-edge-modules-tls-edge-mutual-tls-get) | |
| [replace](#ngrok-api-edge-modules-tls-edge-mutual-tls-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-mutual-tls delete
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-mutual-tls delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-mutual-tls get
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-mutual-tls get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-mutual-tls replace
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-mutual-tls replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.certificate-authority-ids` | list of certificate authorities that will be used to validate the TLS client certificate presented by the initiator of the TLS connection |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-tls-termination
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-tls-edge-tls-termination-delete) | |
| [get](#ngrok-api-edge-modules-tls-edge-tls-termination-get) | |
| [replace](#ngrok-api-edge-modules-tls-edge-tls-termination-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-tls-termination delete
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-tls-termination delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-tls-termination get
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-tls-termination get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-tls-termination replace
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-tls-termination replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.min-version` | The minimum TLS version used for termination and advertised to the client during the TLS handshake. if unspecified, ngrok will choose an industry-safe default. This value must be null if terminate\_at is set to upstream. |
| `--module.terminate-at` | edge if the ngrok edge should terminate TLS traffic, upstream if TLS traffic should be passed through to the upstream ngrok agent / application server for termination. if upstream is chosen, most other modules will be disallowed because they rely on the ngrok edge being able to access the underlying traffic. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-traffic-policy
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-edge-modules-tls-edge-traffic-policy-delete) | |
| [get](#ngrok-api-edge-modules-tls-edge-traffic-policy-get) | |
| [replace](#ngrok-api-edge-modules-tls-edge-traffic-policy-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-traffic-policy delete
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-traffic-policy delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-traffic-policy get
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-traffic-policy get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edge-modules tls-edge-traffic-policy replace
### Usage
```sh theme={null}
ngrok api edge-modules tls-edge-traffic-policy replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.value` | the traffic policy that should be applied to the traffic on your endpoint. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges
### SubCommands
| Command | Description |
| - | - |
| [https](#ngrok-api-edges-https) | |
| [https-routes](#ngrok-api-edges-https-routes) | |
| [tcp](#ngrok-api-edges-tcp) | |
| [tls](#ngrok-api-edges-tls) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges https
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-edges-https-create) | Create an HTTPS Edge |
| [delete](#ngrok-api-edges-https-delete) | Delete an HTTPS Edge by ID |
| [get](#ngrok-api-edges-https-get) | Get an HTTPS Edge by ID |
| [list](#ngrok-api-edges-https-list) | Returns a list of all HTTPS Edges on this account |
| [update](#ngrok-api-edges-https-update) | Updates an HTTPS Edge by ID |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges https create
Create an HTTPS Edge
### Usage
```sh theme={null}
ngrok api edges https create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of what this edge will be used for; optional, max 255 bytes. |
| `--hostports` | hostports served by this edge |
| `--metadata` | arbitrary user-defined machine-readable data of this edge; optional, max 4096 bytes. |
| `--mutual-tls.certificate-authority-ids` | list of certificate authorities that will be used to validate the TLS client certificate presented by the initiator of the TLS connection |
| `--mutual-tls.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--tls-termination.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--tls-termination.min-version` | The minimum TLS version used for termination and advertised to the client during the TLS handshake. if unspecified, ngrok will choose an industry-safe default. This value must be null if terminate\_at is set to upstream. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges https delete
Delete an HTTPS Edge by ID
### Usage
```sh theme={null}
ngrok api edges https delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges https get
Get an HTTPS Edge by ID
### Usage
```sh theme={null}
ngrok api edges https get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges https list
Returns a list of all HTTPS Edges on this account
### Usage
```sh theme={null}
ngrok api edges https list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges https update
Updates an HTTPS Edge by ID. If a module is not specified in the update, it will not be modified. However, each module configuration that is specified will completely replace the existing value. There is no way to delete an existing module via this API, instead use the delete module API.
### Usage
```sh theme={null}
ngrok api edges https update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of what this edge will be used for; optional, max 255 bytes. |
| `--hostports` | hostports served by this edge |
| `--metadata` | arbitrary user-defined machine-readable data of this edge; optional, max 4096 bytes. |
| `--mutual-tls.certificate-authority-ids` | list of certificate authorities that will be used to validate the TLS client certificate presented by the initiator of the TLS connection |
| `--mutual-tls.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--tls-termination.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--tls-termination.min-version` | The minimum TLS version used for termination and advertised to the client during the TLS handshake. if unspecified, ngrok will choose an industry-safe default. This value must be null if terminate\_at is set to upstream. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges https-routes
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-edges-https-routes-create) | Create an HTTPS Edge Route |
| [delete](#ngrok-api-edges-https-routes-delete) | Delete an HTTPS Edge Route by ID |
| [get](#ngrok-api-edges-https-routes-get) | Get an HTTPS Edge Route by ID |
| [update](#ngrok-api-edges-https-routes-update) | Updates an HTTPS Edge Route by ID |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges https-routes create
Create an HTTPS Edge Route
### Usage
```sh theme={null}
ngrok api edges https-routes create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backend.backend-id` | backend to be used to back this endpoint |
| `--backend.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--circuit-breaker.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--circuit-breaker.error-threshold-percentage` | Error threshold percentage should be between 0 - 1.0, not 0-100.0 |
| `--circuit-breaker.num-buckets` | Integer number of buckets into which metrics are retained. Max 128. |
| `--circuit-breaker.rolling-window` | Integer number of seconds in the statistical rolling window that metrics are retained for. |
| `--circuit-breaker.tripped-duration` | Integer number of seconds after which the circuit is tripped to wait before re-evaluating upstream health |
| `--circuit-breaker.volume-threshold` | Integer number of requests in a rolling window that will trip the circuit. Helpful if traffic volume is low. |
| `--compression.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--description` | human-readable description of what this edge will be used for; optional, max 255 bytes. |
| `--ip-restriction.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--ip-restriction.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--match` | Route selector: "/blog" or "example.com" or "example.com/blog" |
| `--match-type` | Type of match to use for this route. Valid values are "exact\_path" and "path\_prefix". |
| `--metadata` | arbitrary user-defined machine-readable data of this edge. Optional, max 4096 bytes. |
| `--oauth.auth-check-interval` | Integer number of seconds after which ngrok guarantees it will refresh user state from the identity provider and recheck whether the user is still authorized to access the endpoint. This is the preferred tunable to use to enforce a minimum amount of time after which a revoked user will no longer be able to access the resource. |
| `--oauth.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--oauth.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--oauth.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--oauth.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--oauth.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--oauth.provider.amazon.client-id` | |
| `--oauth.provider.amazon.client-secret` | |
| `--oauth.provider.amazon.email-addresses` | |
| `--oauth.provider.amazon.email-domains` | |
| `--oauth.provider.amazon.scopes` | |
| `--oauth.provider.facebook.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.facebook.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.facebook.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.facebook.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.facebook.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.github.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.github.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.github.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.github.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.github.organizations` | a list of github org identifiers. users who are members of any of the listed organizations will be allowed access. identifiers should be the organization's 'slug' |
| `--oauth.provider.github.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.github.teams` | a list of github teams identifiers. users will be allowed access to the endpoint if they are a member of any of these teams. identifiers should be in the 'slug' format qualified with the org name, e.g. org-name/team-name |
| `--oauth.provider.gitlab.client-id` | |
| `--oauth.provider.gitlab.client-secret` | |
| `--oauth.provider.gitlab.email-addresses` | |
| `--oauth.provider.gitlab.email-domains` | |
| `--oauth.provider.gitlab.scopes` | |
| `--oauth.provider.google.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.google.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.google.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.google.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.google.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.linkedin.client-id` | |
| `--oauth.provider.linkedin.client-secret` | |
| `--oauth.provider.linkedin.email-addresses` | |
| `--oauth.provider.linkedin.email-domains` | |
| `--oauth.provider.linkedin.scopes` | |
| `--oauth.provider.microsoft.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.microsoft.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.microsoft.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.microsoft.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.microsoft.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.twitch.client-id` | |
| `--oauth.provider.twitch.client-secret` | |
| `--oauth.provider.twitch.email-addresses` | |
| `--oauth.provider.twitch.email-domains` | |
| `--oauth.provider.twitch.scopes` | |
| `--oidc.client-id` | The OIDC app's client ID and OIDC audience. |
| `--oidc.client-secret` | The OIDC app's client secret. |
| `--oidc.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--oidc.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--oidc.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--oidc.issuer` | URL of the OIDC "OpenID provider". This is the base URL used for discovery. |
| `--oidc.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--oidc.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--oidc.scopes` | The set of scopes to request from the OIDC identity provider. |
| `--request-headers.add` | a map of header key to header value that will be injected into the HTTP Request before being sent to the upstream application server |
| `--request-headers.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--request-headers.remove` | a list of header names that will be removed from the HTTP Request before being sent to the upstream application server |
| `--response-headers.add` | a map of header key to header value that will be injected into the HTTP Response returned to the HTTP client |
| `--response-headers.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--response-headers.remove` | a list of header names that will be removed from the HTTP Response returned to the HTTP client |
| `--saml.allow-idp-initiated` | If true, the IdP may initiate a login directly (e.g. the user does not need to visit the endpoint first and then be redirected). The IdP should set the RelayState parameter to the target URL of the resource they want the user to be redirected to after the SAML login assertion has been processed. |
| `--saml.authorized-groups` | If present, only users who are a member of one of the listed groups may access the target endpoint. |
| `--saml.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--saml.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--saml.force-authn` | If true, indicates that whenever we redirect a user to the IdP for authentication that the IdP must prompt the user for authentication credentials even if the user already has a valid session with the IdP. |
| `--saml.idp-metadata` | The full XML IdP EntityDescriptor. Your IdP may provide this to you as a a file to download or as a URL. |
| `--saml.idp-metadata-url` | The IdP's metadata URL which returns the XML IdP EntityDescriptor. The IdP's metadata URL specifies how to connect to the IdP as well as its public key which is then used to validate the signature on incoming SAML assertions to the ACS endpoint. |
| `--saml.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--saml.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--saml.nameid-format` | Defines the name identifier format the SP expects the IdP to use in its assertions to identify subjects. If unspecified, a default value of urn:oasis:names:tc:SAML:2.0:nameid-format:persistent will be used. A subset of the allowed values enumerated by the SAML specification are supported. |
| `--saml.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--traffic-policy.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--traffic-policy.value` | the traffic policy that should be applied to the traffic on your endpoint. |
| `--user-agent-filter.allow` | |
| `--user-agent-filter.deny` | |
| `--user-agent-filter.enabled` | |
| `--webhook-verification.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--webhook-verification.provider` | a string indicating which webhook provider will be sending webhooks to this endpoint. Value must be one of the supported providers defined at [https://ngrok.com/docs/cloud-edge/modules/webhook-verification](https://ngrok.com/docs/cloud-edge/modules/webhook-verification) ([https://ngrok.com/docs/cloud-edge/modules/webhook-verification](https://ngrok.com/docs/cloud-edge/modules/webhook-verification)) |
| `--webhook-verification.secret` | a string secret used to validate requests from the given provider. All providers except AWS SNS require a secret |
| `--websocket-tcp-converter.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges https-routes delete
Delete an HTTPS Edge Route by ID
### Usage
```sh theme={null}
ngrok api edges https-routes delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges https-routes get
Get an HTTPS Edge Route by ID
### Usage
```sh theme={null}
ngrok api edges https-routes get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges https-routes update
Updates an HTTPS Edge Route by ID. If a module is not specified in the update, it will not be modified. However, each module configuration that is specified will completely replace the existing value. There is no way to delete an existing module via this API, instead use the delete module API.
### Usage
```sh theme={null}
ngrok api edges https-routes update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backend.backend-id` | backend to be used to back this endpoint |
| `--backend.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--circuit-breaker.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--circuit-breaker.error-threshold-percentage` | Error threshold percentage should be between 0 - 1.0, not 0-100.0 |
| `--circuit-breaker.num-buckets` | Integer number of buckets into which metrics are retained. Max 128. |
| `--circuit-breaker.rolling-window` | Integer number of seconds in the statistical rolling window that metrics are retained for. |
| `--circuit-breaker.tripped-duration` | Integer number of seconds after which the circuit is tripped to wait before re-evaluating upstream health |
| `--circuit-breaker.volume-threshold` | Integer number of requests in a rolling window that will trip the circuit. Helpful if traffic volume is low. |
| `--compression.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--description` | human-readable description of what this edge will be used for; optional, max 255 bytes. |
| `--ip-restriction.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--ip-restriction.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--match` | Route selector: "/blog" or "example.com" or "example.com/blog" |
| `--match-type` | Type of match to use for this route. Valid values are "exact\_path" and "path\_prefix". |
| `--metadata` | arbitrary user-defined machine-readable data of this edge. Optional, max 4096 bytes. |
| `--oauth.auth-check-interval` | Integer number of seconds after which ngrok guarantees it will refresh user state from the identity provider and recheck whether the user is still authorized to access the endpoint. This is the preferred tunable to use to enforce a minimum amount of time after which a revoked user will no longer be able to access the resource. |
| `--oauth.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--oauth.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--oauth.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--oauth.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--oauth.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--oauth.provider.amazon.client-id` | |
| `--oauth.provider.amazon.client-secret` | |
| `--oauth.provider.amazon.email-addresses` | |
| `--oauth.provider.amazon.email-domains` | |
| `--oauth.provider.amazon.scopes` | |
| `--oauth.provider.facebook.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.facebook.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.facebook.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.facebook.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.facebook.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.github.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.github.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.github.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.github.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.github.organizations` | a list of github org identifiers. users who are members of any of the listed organizations will be allowed access. identifiers should be the organization's 'slug' |
| `--oauth.provider.github.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.github.teams` | a list of github teams identifiers. users will be allowed access to the endpoint if they are a member of any of these teams. identifiers should be in the 'slug' format qualified with the org name, e.g. org-name/team-name |
| `--oauth.provider.gitlab.client-id` | |
| `--oauth.provider.gitlab.client-secret` | |
| `--oauth.provider.gitlab.email-addresses` | |
| `--oauth.provider.gitlab.email-domains` | |
| `--oauth.provider.gitlab.scopes` | |
| `--oauth.provider.google.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.google.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.google.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.google.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.google.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.linkedin.client-id` | |
| `--oauth.provider.linkedin.client-secret` | |
| `--oauth.provider.linkedin.email-addresses` | |
| `--oauth.provider.linkedin.email-domains` | |
| `--oauth.provider.linkedin.scopes` | |
| `--oauth.provider.microsoft.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.microsoft.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.microsoft.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.microsoft.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.microsoft.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.twitch.client-id` | |
| `--oauth.provider.twitch.client-secret` | |
| `--oauth.provider.twitch.email-addresses` | |
| `--oauth.provider.twitch.email-domains` | |
| `--oauth.provider.twitch.scopes` | |
| `--oidc.client-id` | The OIDC app's client ID and OIDC audience. |
| `--oidc.client-secret` | The OIDC app's client secret. |
| `--oidc.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--oidc.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--oidc.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--oidc.issuer` | URL of the OIDC "OpenID provider". This is the base URL used for discovery. |
| `--oidc.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--oidc.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--oidc.scopes` | The set of scopes to request from the OIDC identity provider. |
| `--request-headers.add` | a map of header key to header value that will be injected into the HTTP Request before being sent to the upstream application server |
| `--request-headers.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--request-headers.remove` | a list of header names that will be removed from the HTTP Request before being sent to the upstream application server |
| `--response-headers.add` | a map of header key to header value that will be injected into the HTTP Response returned to the HTTP client |
| `--response-headers.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--response-headers.remove` | a list of header names that will be removed from the HTTP Response returned to the HTTP client |
| `--saml.allow-idp-initiated` | If true, the IdP may initiate a login directly (e.g. the user does not need to visit the endpoint first and then be redirected). The IdP should set the RelayState parameter to the target URL of the resource they want the user to be redirected to after the SAML login assertion has been processed. |
| `--saml.authorized-groups` | If present, only users who are a member of one of the listed groups may access the target endpoint. |
| `--saml.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--saml.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--saml.force-authn` | If true, indicates that whenever we redirect a user to the IdP for authentication that the IdP must prompt the user for authentication credentials even if the user already has a valid session with the IdP. |
| `--saml.idp-metadata` | The full XML IdP EntityDescriptor. Your IdP may provide this to you as a a file to download or as a URL. |
| `--saml.idp-metadata-url` | The IdP's metadata URL which returns the XML IdP EntityDescriptor. The IdP's metadata URL specifies how to connect to the IdP as well as its public key which is then used to validate the signature on incoming SAML assertions to the ACS endpoint. |
| `--saml.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--saml.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--saml.nameid-format` | Defines the name identifier format the SP expects the IdP to use in its assertions to identify subjects. If unspecified, a default value of urn:oasis:names:tc:SAML:2.0:nameid-format:persistent will be used. A subset of the allowed values enumerated by the SAML specification are supported. |
| `--saml.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--traffic-policy.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--traffic-policy.value` | the traffic policy that should be applied to the traffic on your endpoint. |
| `--user-agent-filter.allow` | |
| `--user-agent-filter.deny` | |
| `--user-agent-filter.enabled` | |
| `--webhook-verification.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--webhook-verification.provider` | a string indicating which webhook provider will be sending webhooks to this endpoint. Value must be one of the supported providers defined at [https://ngrok.com/docs/cloud-edge/modules/webhook-verification](https://ngrok.com/docs/cloud-edge/modules/webhook-verification) ([https://ngrok.com/docs/cloud-edge/modules/webhook-verification](https://ngrok.com/docs/cloud-edge/modules/webhook-verification)) |
| `--webhook-verification.secret` | a string secret used to validate requests from the given provider. All providers except AWS SNS require a secret |
| `--websocket-tcp-converter.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tcp
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-edges-tcp-create) | Create a TCP Edge |
| [delete](#ngrok-api-edges-tcp-delete) | Delete a TCP Edge by ID |
| [get](#ngrok-api-edges-tcp-get) | Get a TCP Edge by ID |
| [list](#ngrok-api-edges-tcp-list) | Returns a list of all TCP Edges on this account |
| [update](#ngrok-api-edges-tcp-update) | Updates a TCP Edge by ID |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tcp create
Create a TCP Edge
### Usage
```sh theme={null}
ngrok api edges tcp create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backend.backend-id` | backend to be used to back this endpoint |
| `--backend.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--description` | human-readable description of what this edge will be used for; optional, max 255 bytes. |
| `--hostports` | hostports served by this edge |
| `--ip-restriction.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--ip-restriction.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--metadata` | arbitrary user-defined machine-readable data of this edge. Optional, max 4096 bytes. |
| `--traffic-policy.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--traffic-policy.value` | the traffic policy that should be applied to the traffic on your endpoint. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tcp delete
Delete a TCP Edge by ID
### Usage
```sh theme={null}
ngrok api edges tcp delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tcp get
Get a TCP Edge by ID
### Usage
```sh theme={null}
ngrok api edges tcp get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tcp list
Returns a list of all TCP Edges on this account
### Usage
```sh theme={null}
ngrok api edges tcp list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tcp update
Updates a TCP Edge by ID. If a module is not specified in the update, it will not be modified. However, each module configuration that is specified will completely replace the existing value. There is no way to delete an existing module via this API, instead use the delete module API.
### Usage
```sh theme={null}
ngrok api edges tcp update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backend.backend-id` | backend to be used to back this endpoint |
| `--backend.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--description` | human-readable description of what this edge will be used for; optional, max 255 bytes. |
| `--hostports` | hostports served by this edge |
| `--ip-restriction.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--ip-restriction.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--metadata` | arbitrary user-defined machine-readable data of this edge. Optional, max 4096 bytes. |
| `--traffic-policy.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--traffic-policy.value` | the traffic policy that should be applied to the traffic on your endpoint. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tls
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-edges-tls-create) | Create a TLS Edge |
| [delete](#ngrok-api-edges-tls-delete) | Delete a TLS Edge by ID |
| [get](#ngrok-api-edges-tls-get) | Get a TLS Edge by ID |
| [list](#ngrok-api-edges-tls-list) | Returns a list of all TLS Edges on this account |
| [update](#ngrok-api-edges-tls-update) | Updates a TLS Edge by ID |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tls create
Create a TLS Edge
### Usage
```sh theme={null}
ngrok api edges tls create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backend.backend-id` | backend to be used to back this endpoint |
| `--backend.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--description` | human-readable description of what this edge will be used for; optional, max 255 bytes. |
| `--hostports` | hostports served by this edge |
| `--ip-restriction.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--ip-restriction.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--metadata` | arbitrary user-defined machine-readable data of this edge. Optional, max 4096 bytes. |
| `--mutual-tls.certificate-authority-ids` | list of certificate authorities that will be used to validate the TLS client certificate presented by the initiator of the TLS connection |
| `--mutual-tls.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--tls-termination.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--tls-termination.min-version` | The minimum TLS version used for termination and advertised to the client during the TLS handshake. if unspecified, ngrok will choose an industry-safe default. This value must be null if terminate\_at is set to upstream. |
| `--tls-termination.terminate-at` | edge if the ngrok edge should terminate TLS traffic, upstream if TLS traffic should be passed through to the upstream ngrok agent / application server for termination. if upstream is chosen, most other modules will be disallowed because they rely on the ngrok edge being able to access the underlying traffic. |
| `--traffic-policy.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--traffic-policy.value` | the traffic policy that should be applied to the traffic on your endpoint. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tls delete
Delete a TLS Edge by ID
### Usage
```sh theme={null}
ngrok api edges tls delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tls get
Get a TLS Edge by ID
### Usage
```sh theme={null}
ngrok api edges tls get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tls list
Returns a list of all TLS Edges on this account
### Usage
```sh theme={null}
ngrok api edges tls list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api edges tls update
Updates a TLS Edge by ID. If a module is not specified in the update, it will not be modified. However, each module configuration that is specified will completely replace the existing value. There is no way to delete an existing module via this API, instead use the delete module API.
### Usage
```sh theme={null}
ngrok api edges tls update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backend.backend-id` | backend to be used to back this endpoint |
| `--backend.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--description` | human-readable description of what this edge will be used for; optional, max 255 bytes. |
| `--hostports` | hostports served by this edge |
| `--ip-restriction.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--ip-restriction.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--metadata` | arbitrary user-defined machine-readable data of this edge. Optional, max 4096 bytes. |
| `--mutual-tls.certificate-authority-ids` | list of certificate authorities that will be used to validate the TLS client certificate presented by the initiator of the TLS connection |
| `--mutual-tls.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--tls-termination.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--tls-termination.min-version` | The minimum TLS version used for termination and advertised to the client during the TLS handshake. if unspecified, ngrok will choose an industry-safe default. This value must be null if terminate\_at is set to upstream. |
| `--tls-termination.terminate-at` | edge if the ngrok edge should terminate TLS traffic, upstream if TLS traffic should be passed through to the upstream ngrok agent / application server for termination. if upstream is chosen, most other modules will be disallowed because they rely on the ngrok edge being able to access the underlying traffic. |
| `--traffic-policy.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--traffic-policy.value` | the traffic policy that should be applied to the traffic on your endpoint. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoint-configurations
Endpoint Configurations are a reusable group of modules that encapsulate how
traffic to a domain or address is handled. Endpoint configurations are only
applied to Domains and TCP Addresses they have been attached to.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-endpoint-configurations-create) | Create a new endpoint configuration |
| [delete](#ngrok-api-endpoint-configurations-delete) | Delete an endpoint configuration |
| [get](#ngrok-api-endpoint-configurations-get) | Returns detailed information about an endpoint... |
| [list](#ngrok-api-endpoint-configurations-list) | Returns a list of all endpoint configurations... |
| [update](#ngrok-api-endpoint-configurations-update) | Updates an endpoint configuration |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoint-configurations create
Create a new endpoint configuration
### Usage
```sh theme={null}
ngrok api endpoint-configurations create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backend.backend-id` | backend to be used to back this endpoint |
| `--backend.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--basic-auth.allow-options` | true or false indicating whether to allow OPTIONS requests through without authentication which is necessary for CORS. default is false |
| `--basic-auth.auth-provider-id` | determines how the basic auth credentials are validated. Currently only the value agent is supported which means that credentials will be validated against the username and password specified by the ngrok agent's --basic-auth flag, if any. |
| `--basic-auth.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--basic-auth.realm` | an arbitrary string to be specified in as the 'realm' value in the WWW-Authenticate header. default is ngrok |
| `--circuit-breaker.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--circuit-breaker.error-threshold-percentage` | Error threshold percentage should be between 0 - 1.0, not 0-100.0 |
| `--circuit-breaker.num-buckets` | Integer number of buckets into which metrics are retained. Max 128. |
| `--circuit-breaker.rolling-window` | Integer number of seconds in the statistical rolling window that metrics are retained for. |
| `--circuit-breaker.tripped-duration` | Integer number of seconds after which the circuit is tripped to wait before re-evaluating upstream health |
| `--circuit-breaker.volume-threshold` | Integer number of requests in a rolling window that will trip the circuit. Helpful if traffic volume is low. |
| `--compression.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--description` | human-readable description of what this endpoint configuration will be do when applied or what traffic it will be applied to. Optional, max 255 bytes |
| `--ip-policy.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--ip-policy.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--metadata` | arbitrary user-defined machine-readable data of this endpoint configuration. Optional, max 4096 bytes. |
| `--mutual-tls.certificate-authority-ids` | list of certificate authorities that will be used to validate the TLS client certificate presented by the initiator of the TLS connection |
| `--mutual-tls.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--oauth.auth-check-interval` | Integer number of seconds after which ngrok guarantees it will refresh user state from the identity provider and recheck whether the user is still authorized to access the endpoint. This is the preferred tunable to use to enforce a minimum amount of time after which a revoked user will no longer be able to access the resource. |
| `--oauth.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--oauth.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--oauth.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--oauth.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--oauth.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--oauth.provider.amazon.client-id` | |
| `--oauth.provider.amazon.client-secret` | |
| `--oauth.provider.amazon.email-addresses` | |
| `--oauth.provider.amazon.email-domains` | |
| `--oauth.provider.amazon.scopes` | |
| `--oauth.provider.facebook.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.facebook.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.facebook.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.facebook.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.facebook.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.github.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.github.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.github.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.github.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.github.organizations` | a list of github org identifiers. users who are members of any of the listed organizations will be allowed access. identifiers should be the organization's 'slug' |
| `--oauth.provider.github.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.github.teams` | a list of github teams identifiers. users will be allowed access to the endpoint if they are a member of any of these teams. identifiers should be in the 'slug' format qualified with the org name, e.g. org-name/team-name |
| `--oauth.provider.gitlab.client-id` | |
| `--oauth.provider.gitlab.client-secret` | |
| `--oauth.provider.gitlab.email-addresses` | |
| `--oauth.provider.gitlab.email-domains` | |
| `--oauth.provider.gitlab.scopes` | |
| `--oauth.provider.google.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.google.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.google.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.google.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.google.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.linkedin.client-id` | |
| `--oauth.provider.linkedin.client-secret` | |
| `--oauth.provider.linkedin.email-addresses` | |
| `--oauth.provider.linkedin.email-domains` | |
| `--oauth.provider.linkedin.scopes` | |
| `--oauth.provider.microsoft.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.microsoft.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.microsoft.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.microsoft.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.microsoft.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.twitch.client-id` | |
| `--oauth.provider.twitch.client-secret` | |
| `--oauth.provider.twitch.email-addresses` | |
| `--oauth.provider.twitch.email-domains` | |
| `--oauth.provider.twitch.scopes` | |
| `--oidc.client-id` | The OIDC app's client ID and OIDC audience. |
| `--oidc.client-secret` | The OIDC app's client secret. |
| `--oidc.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--oidc.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--oidc.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--oidc.issuer` | URL of the OIDC "OpenID provider". This is the base URL used for discovery. |
| `--oidc.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--oidc.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--oidc.scopes` | The set of scopes to request from the OIDC identity provider. |
| `--request-headers.add` | a map of header key to header value that will be injected into the HTTP Request before being sent to the upstream application server |
| `--request-headers.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--request-headers.remove` | a list of header names that will be removed from the HTTP Request before being sent to the upstream application server |
| `--response-headers.add` | a map of header key to header value that will be injected into the HTTP Response returned to the HTTP client |
| `--response-headers.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--response-headers.remove` | a list of header names that will be removed from the HTTP Response returned to the HTTP client |
| `--saml.allow-idp-initiated` | If true, the IdP may initiate a login directly (e.g. the user does not need to visit the endpoint first and then be redirected). The IdP should set the RelayState parameter to the target URL of the resource they want the user to be redirected to after the SAML login assertion has been processed. |
| `--saml.authorized-groups` | If present, only users who are a member of one of the listed groups may access the target endpoint. |
| `--saml.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--saml.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--saml.force-authn` | If true, indicates that whenever we redirect a user to the IdP for authentication that the IdP must prompt the user for authentication credentials even if the user already has a valid session with the IdP. |
| `--saml.idp-metadata` | The full XML IdP EntityDescriptor. Your IdP may provide this to you as a a file to download or as a URL. |
| `--saml.idp-metadata-url` | The IdP's metadata URL which returns the XML IdP EntityDescriptor. The IdP's metadata URL specifies how to connect to the IdP as well as its public key which is then used to validate the signature on incoming SAML assertions to the ACS endpoint. |
| `--saml.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--saml.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--saml.nameid-format` | Defines the name identifier format the SP expects the IdP to use in its assertions to identify subjects. If unspecified, a default value of urn:oasis:names:tc:SAML:2.0:nameid-format:persistent will be used. A subset of the allowed values enumerated by the SAML specification are supported. |
| `--saml.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--tls-termination.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--tls-termination.min-version` | The minimum TLS version used for termination and advertised to the client during the TLS handshake. if unspecified, ngrok will choose an industry-safe default. This value must be null if terminate\_at is set to upstream. |
| `--tls-termination.terminate-at` | edge if the ngrok edge should terminate TLS traffic, upstream if TLS traffic should be passed through to the upstream ngrok agent / application server for termination. if upstream is chosen, most other modules will be disallowed because they rely on the ngrok edge being able to access the underlying traffic. |
| `--type` | they type of traffic this endpoint configuration can be applied to. one of: http, https, tcp |
| `--webhook-validation.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--webhook-validation.provider` | a string indicating which webhook provider will be sending webhooks to this endpoint. Value must be one of the supported providers defined at [https://ngrok.com/docs/cloud-edge/modules/webhook-verification](https://ngrok.com/docs/cloud-edge/modules/webhook-verification) ([https://ngrok.com/docs/cloud-edge/modules/webhook-verification](https://ngrok.com/docs/cloud-edge/modules/webhook-verification)) |
| `--webhook-validation.secret` | a string secret used to validate requests from the given provider. All providers except AWS SNS require a secret |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoint-configurations delete
Delete an endpoint configuration. This operation will fail if the endpoint configuration is still referenced by any reserved domain or reserved address.
### Usage
```sh theme={null}
ngrok api endpoint-configurations delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoint-configurations get
Returns detailed information about an endpoint configuration
### Usage
```sh theme={null}
ngrok api endpoint-configurations get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoint-configurations list
Returns a list of all endpoint configurations on this account
### Usage
```sh theme={null}
ngrok api endpoint-configurations list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoint-configurations update
Updates an endpoint configuration. If a module is not specified in the update, it will not be modified. However, each module configuration that is specified will completely replace the existing value. There is no way to delete an existing module via this API, instead use the delete module API.
### Usage
```sh theme={null}
ngrok api endpoint-configurations update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--backend.backend-id` | backend to be used to back this endpoint |
| `--backend.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--basic-auth.allow-options` | true or false indicating whether to allow OPTIONS requests through without authentication which is necessary for CORS. default is false |
| `--basic-auth.auth-provider-id` | determines how the basic auth credentials are validated. Currently only the value agent is supported which means that credentials will be validated against the username and password specified by the ngrok agent's --basic-auth flag, if any. |
| `--basic-auth.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--basic-auth.realm` | an arbitrary string to be specified in as the 'realm' value in the WWW-Authenticate header. default is ngrok |
| `--circuit-breaker.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--circuit-breaker.error-threshold-percentage` | Error threshold percentage should be between 0 - 1.0, not 0-100.0 |
| `--circuit-breaker.num-buckets` | Integer number of buckets into which metrics are retained. Max 128. |
| `--circuit-breaker.rolling-window` | Integer number of seconds in the statistical rolling window that metrics are retained for. |
| `--circuit-breaker.tripped-duration` | Integer number of seconds after which the circuit is tripped to wait before re-evaluating upstream health |
| `--circuit-breaker.volume-threshold` | Integer number of requests in a rolling window that will trip the circuit. Helpful if traffic volume is low. |
| `--compression.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--description` | human-readable description of what this endpoint configuration will be do when applied or what traffic it will be applied to. Optional, max 255 bytes |
| `--ip-policy.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--ip-policy.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--metadata` | arbitrary user-defined machine-readable data of this endpoint configuration. Optional, max 4096 bytes. |
| `--mutual-tls.certificate-authority-ids` | list of certificate authorities that will be used to validate the TLS client certificate presented by the initiator of the TLS connection |
| `--mutual-tls.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--oauth.auth-check-interval` | Integer number of seconds after which ngrok guarantees it will refresh user state from the identity provider and recheck whether the user is still authorized to access the endpoint. This is the preferred tunable to use to enforce a minimum amount of time after which a revoked user will no longer be able to access the resource. |
| `--oauth.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--oauth.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--oauth.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--oauth.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--oauth.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--oauth.provider.amazon.client-id` | |
| `--oauth.provider.amazon.client-secret` | |
| `--oauth.provider.amazon.email-addresses` | |
| `--oauth.provider.amazon.email-domains` | |
| `--oauth.provider.amazon.scopes` | |
| `--oauth.provider.facebook.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.facebook.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.facebook.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.facebook.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.facebook.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.github.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.github.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.github.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.github.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.github.organizations` | a list of github org identifiers. users who are members of any of the listed organizations will be allowed access. identifiers should be the organization's 'slug' |
| `--oauth.provider.github.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.github.teams` | a list of github teams identifiers. users will be allowed access to the endpoint if they are a member of any of these teams. identifiers should be in the 'slug' format qualified with the org name, e.g. org-name/team-name |
| `--oauth.provider.gitlab.client-id` | |
| `--oauth.provider.gitlab.client-secret` | |
| `--oauth.provider.gitlab.email-addresses` | |
| `--oauth.provider.gitlab.email-domains` | |
| `--oauth.provider.gitlab.scopes` | |
| `--oauth.provider.google.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.google.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.google.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.google.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.google.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.linkedin.client-id` | |
| `--oauth.provider.linkedin.client-secret` | |
| `--oauth.provider.linkedin.email-addresses` | |
| `--oauth.provider.linkedin.email-domains` | |
| `--oauth.provider.linkedin.scopes` | |
| `--oauth.provider.microsoft.client-id` | the OAuth app client ID. retrieve it from the identity provider's dashboard where you created your own OAuth app. optional. if unspecified, ngrok will use its own managed oauth application which has additional restrictions. see the OAuth module docs for more details. if present, client\_secret must be present as well. |
| `--oauth.provider.microsoft.client-secret` | the OAuth app client secret. retrieve if from the identity provider's dashboard where you created your own OAuth app. optional, see all of the caveats in the docs for client\_id. |
| `--oauth.provider.microsoft.email-addresses` | a list of email addresses of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.microsoft.email-domains` | a list of email domains of users authenticated by identity provider who are allowed access to the endpoint |
| `--oauth.provider.microsoft.scopes` | a list of provider-specific OAuth scopes with the permissions your OAuth app would like to ask for. these may not be set if you are using the ngrok-managed oauth app (i.e. you must pass both client\_id and client\_secret to set scopes) |
| `--oauth.provider.twitch.client-id` | |
| `--oauth.provider.twitch.client-secret` | |
| `--oauth.provider.twitch.email-addresses` | |
| `--oauth.provider.twitch.email-domains` | |
| `--oauth.provider.twitch.scopes` | |
| `--oidc.client-id` | The OIDC app's client ID and OIDC audience. |
| `--oidc.client-secret` | The OIDC app's client secret. |
| `--oidc.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--oidc.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--oidc.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--oidc.issuer` | URL of the OIDC "OpenID provider". This is the base URL used for discovery. |
| `--oidc.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--oidc.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--oidc.scopes` | The set of scopes to request from the OIDC identity provider. |
| `--request-headers.add` | a map of header key to header value that will be injected into the HTTP Request before being sent to the upstream application server |
| `--request-headers.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--request-headers.remove` | a list of header names that will be removed from the HTTP Request before being sent to the upstream application server |
| `--response-headers.add` | a map of header key to header value that will be injected into the HTTP Response returned to the HTTP client |
| `--response-headers.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--response-headers.remove` | a list of header names that will be removed from the HTTP Response returned to the HTTP client |
| `--saml.allow-idp-initiated` | If true, the IdP may initiate a login directly (e.g. the user does not need to visit the endpoint first and then be redirected). The IdP should set the RelayState parameter to the target URL of the resource they want the user to be redirected to after the SAML login assertion has been processed. |
| `--saml.authorized-groups` | If present, only users who are a member of one of the listed groups may access the target endpoint. |
| `--saml.cookie-prefix` | the prefix of the session cookie that ngrok sets on the http client to cache authentication. default is 'ngrok.' |
| `--saml.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--saml.force-authn` | If true, indicates that whenever we redirect a user to the IdP for authentication that the IdP must prompt the user for authentication credentials even if the user already has a valid session with the IdP. |
| `--saml.idp-metadata` | The full XML IdP EntityDescriptor. Your IdP may provide this to you as a a file to download or as a URL. |
| `--saml.idp-metadata-url` | The IdP's metadata URL which returns the XML IdP EntityDescriptor. The IdP's metadata URL specifies how to connect to the IdP as well as its public key which is then used to validate the signature on incoming SAML assertions to the ACS endpoint. |
| `--saml.inactivity-timeout` | Integer number of seconds of inactivity after which if the user has not accessed the endpoint, their session will time out and they will be forced to reauthenticate. |
| `--saml.maximum-duration` | Integer number of seconds of the maximum duration of an authenticated session. After this period is exceeded, a user must reauthenticate. |
| `--saml.nameid-format` | Defines the name identifier format the SP expects the IdP to use in its assertions to identify subjects. If unspecified, a default value of urn:oasis:names:tc:SAML:2.0:nameid-format:persistent will be used. A subset of the allowed values enumerated by the SAML specification are supported. |
| `--saml.options-passthrough` | Do not enforce authentication on HTTP OPTIONS requests. necessary if you are supporting CORS. |
| `--tls-termination.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--tls-termination.min-version` | The minimum TLS version used for termination and advertised to the client during the TLS handshake. if unspecified, ngrok will choose an industry-safe default. This value must be null if terminate\_at is set to upstream. |
| `--tls-termination.terminate-at` | edge if the ngrok edge should terminate TLS traffic, upstream if TLS traffic should be passed through to the upstream ngrok agent / application server for termination. if upstream is chosen, most other modules will be disallowed because they rely on the ngrok edge being able to access the underlying traffic. |
| `--webhook-validation.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--webhook-validation.provider` | a string indicating which webhook provider will be sending webhooks to this endpoint. Value must be one of the supported providers defined at [https://ngrok.com/docs/cloud-edge/modules/webhook-verification](https://ngrok.com/docs/cloud-edge/modules/webhook-verification) ([https://ngrok.com/docs/cloud-edge/modules/webhook-verification](https://ngrok.com/docs/cloud-edge/modules/webhook-verification)) |
| `--webhook-validation.secret` | a string secret used to validate requests from the given provider. All providers except AWS SNS require a secret |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoints
Endpoints provides an API for querying the endpoint objects
which define what tunnel or edge is used to serve a hostport.
Only active endpoints associated with a tunnel or backend are returned.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-endpoints-create) | Create an endpoint, ... |
| [delete](#ngrok-api-endpoints-delete) | Delete an Endpoint by ID, ... |
| [get](#ngrok-api-endpoints-get) | Get the status of an endpoint by ID |
| [list](#ngrok-api-endpoints-list) | List all active endpoints on the account |
| [update](#ngrok-api-endpoints-update) | Update an Endpoint by ID, ... |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoints create
Create an endpoint, currently available only for cloud endpoints
### Usage
```sh theme={null}
ngrok api endpoints create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--bindings` | the bindings associated with this endpoint |
| `--description` | user-supplied description of the associated tunnel |
| `--metadata` | user-supplied metadata of the associated tunnel or edge object |
| `--pooling-enabled` | |
| `--traffic-policy` | The traffic policy attached to this endpoint |
| `--traffic-policy-file` | The traffic policy attached to this endpoint (path to a file) |
| `--traffic-policy-url` | The traffic policy attached to this endpoint (URL to fetch from) |
| `--type` | Type of endpoint. Only 'cloud' is currently supported (represents a cloud endpoint). Defaults to 'cloud' if not specified. |
| `--url` | the url of the endpoint |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoints delete
Delete an Endpoint by ID, currently available only for cloud endpoints
### Usage
```sh theme={null}
ngrok api endpoints delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoints get
Get the status of an endpoint by ID
### Usage
```sh theme={null}
ngrok api endpoints get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoints list
List all active endpoints on the account
### Usage
```sh theme={null}
ngrok api endpoints list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | Expects a resource ID as its input. Returns earlier entries in the result set, sorted by ID. |
| `--filter` | A CEL expression to filter the list results. Supports logical and comparison operators to match on fields such as id, metadata, created\_at, and more. See ngrok API Filtering for syntax and field details: [https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering) ([https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering)). |
| `--limit` | Constrains the number of results in the dataset. See the API Overview ([https://ngrok.com/docs/api/index#pagination](https://ngrok.com/docs/api/index#pagination)) for details. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api endpoints update
Update an Endpoint by ID, currently available only for cloud endpoints
### Usage
```sh theme={null}
ngrok api endpoints update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--bindings` | the bindings associated with this endpoint |
| `--description` | user-supplied description of the associated tunnel |
| `--metadata` | user-supplied metadata of the associated tunnel or edge object |
| `--pooling-enabled` | |
| `--traffic-policy` | The traffic policy attached to this endpoint |
| `--traffic-policy-file` | The traffic policy attached to this endpoint (path to a file) |
| `--traffic-policy-url` | The traffic policy attached to this endpoint (URL to fetch from) |
| `--url` | the url of the endpoint |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-destinations
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-event-destinations-create) | Create a new Event Destination |
| [delete](#ngrok-api-event-destinations-delete) | Delete an Event Destination |
| [get](#ngrok-api-event-destinations-get) | Get detailed information about an Event... |
| [list](#ngrok-api-event-destinations-list) | List all Event Destinations on this account. |
| [send-test-event](#ngrok-api-event-destinations-send-test-event) | Send a test event to an Event Destination |
| [update](#ngrok-api-event-destinations-update) | Update attributes of an Event Destination. |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-destinations create
Create a new Event Destination. It will not apply to anything until it is associated with an Event Subscription.
### Usage
```sh theme={null}
ngrok api event-destinations create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | Human-readable description of the Event Destination. Optional, max 255 bytes. |
| `--format` | The output format you would like to serialize events into when sending to their target. Currently the only accepted value is JSON. |
| `--metadata` | Arbitrary user-defined machine-readable data of this Event Destination. Optional, max 4096 bytes. |
| `--target.azure-logs-ingestion.client-id` | Client ID for the application client |
| `--target.azure-logs-ingestion.client-secret` | Client Secret for the application client |
| `--target.azure-logs-ingestion.data-collection-rule-id` | Data collection rule immutable ID |
| `--target.azure-logs-ingestion.data-collection-stream-name` | Data collection stream name to use as destination, located inside the DCR |
| `--target.azure-logs-ingestion.logs-ingestion-uri` | Data collection endpoint logs ingestion URI |
| `--target.azure-logs-ingestion.tenant-id` | Tenant ID for the Azure account |
| `--target.cloudwatch-logs.auth.creds.aws-access-key-id` | The ID portion of an AWS access key. |
| `--target.cloudwatch-logs.auth.creds.aws-secret-access-key` | The secret portion of an AWS access key. |
| `--target.cloudwatch-logs.auth.role.role-arn` | An ARN that specifies the role that ngrok should use to deliver to the configured target. |
| `--target.cloudwatch-logs.log-group-arn` | An Amazon Resource Name specifying the CloudWatch Logs group to deposit events into. |
| `--target.datadog.api-key` | Datadog API key to use. |
| `--target.datadog.ddsite` | Datadog site to send event to. |
| `--target.datadog.ddtags` | Tags to send with the event. |
| `--target.datadog.service` | Service name to send with the event. |
| `--target.debug.callback-url` | URL to send events to. |
| `--target.debug.log` | Whether or not to output to publisher service logs. |
| `--target.firehose.auth.creds.aws-access-key-id` | The ID portion of an AWS access key. |
| `--target.firehose.auth.creds.aws-secret-access-key` | The secret portion of an AWS access key. |
| `--target.firehose.auth.role.role-arn` | An ARN that specifies the role that ngrok should use to deliver to the configured target. |
| `--target.firehose.delivery-stream-arn` | An Amazon Resource Name specifying the Firehose delivery stream to deposit events into. |
| `--target.kinesis.auth.creds.aws-access-key-id` | The ID portion of an AWS access key. |
| `--target.kinesis.auth.creds.aws-secret-access-key` | The secret portion of an AWS access key. |
| `--target.kinesis.auth.role.role-arn` | An ARN that specifies the role that ngrok should use to deliver to the configured target. |
| `--target.kinesis.stream-arn` | An Amazon Resource Name specifying the Kinesis stream to deposit events into. |
| `--verify-with-test-event` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-destinations delete
Delete an Event Destination. If the Event Destination is still referenced by an Event Subscription.
### Usage
```sh theme={null}
ngrok api event-destinations delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-destinations get
Get detailed information about an Event Destination by ID.
### Usage
```sh theme={null}
ngrok api event-destinations get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-destinations list
List all Event Destinations on this account.
### Usage
```sh theme={null}
ngrok api event-destinations list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | Expects a resource ID as its input. Returns earlier entries in the result set, sorted by ID. |
| `--filter` | A CEL expression to filter the list results. Supports logical and comparison operators to match on fields such as id, metadata, created\_at, and more. See ngrok API Filtering for syntax and field details: [https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering) ([https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering)). |
| `--limit` | Constrains the number of results in the dataset. See the API Overview ([https://ngrok.com/docs/api/index#pagination](https://ngrok.com/docs/api/index#pagination)) for details. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-destinations send-test-event
Send a test event to an Event Destination
### Usage
```sh theme={null}
ngrok api event-destinations send-test-event [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-destinations update
Update attributes of an Event Destination.
### Usage
```sh theme={null}
ngrok api event-destinations update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | Human-readable description of the Event Destination. Optional, max 255 bytes. |
| `--format` | The output format you would like to serialize events into when sending to their target. Currently the only accepted value is JSON. |
| `--metadata` | Arbitrary user-defined machine-readable data of this Event Destination. Optional, max 4096 bytes. |
| `--target.azure-logs-ingestion.client-id` | Client ID for the application client |
| `--target.azure-logs-ingestion.client-secret` | Client Secret for the application client |
| `--target.azure-logs-ingestion.data-collection-rule-id` | Data collection rule immutable ID |
| `--target.azure-logs-ingestion.data-collection-stream-name` | Data collection stream name to use as destination, located inside the DCR |
| `--target.azure-logs-ingestion.logs-ingestion-uri` | Data collection endpoint logs ingestion URI |
| `--target.azure-logs-ingestion.tenant-id` | Tenant ID for the Azure account |
| `--target.cloudwatch-logs.auth.creds.aws-access-key-id` | The ID portion of an AWS access key. |
| `--target.cloudwatch-logs.auth.creds.aws-secret-access-key` | The secret portion of an AWS access key. |
| `--target.cloudwatch-logs.auth.role.role-arn` | An ARN that specifies the role that ngrok should use to deliver to the configured target. |
| `--target.cloudwatch-logs.log-group-arn` | An Amazon Resource Name specifying the CloudWatch Logs group to deposit events into. |
| `--target.datadog.api-key` | Datadog API key to use. |
| `--target.datadog.ddsite` | Datadog site to send event to. |
| `--target.datadog.ddtags` | Tags to send with the event. |
| `--target.datadog.service` | Service name to send with the event. |
| `--target.debug.callback-url` | URL to send events to. |
| `--target.debug.log` | Whether or not to output to publisher service logs. |
| `--target.firehose.auth.creds.aws-access-key-id` | The ID portion of an AWS access key. |
| `--target.firehose.auth.creds.aws-secret-access-key` | The secret portion of an AWS access key. |
| `--target.firehose.auth.role.role-arn` | An ARN that specifies the role that ngrok should use to deliver to the configured target. |
| `--target.firehose.delivery-stream-arn` | An Amazon Resource Name specifying the Firehose delivery stream to deposit events into. |
| `--target.kinesis.auth.creds.aws-access-key-id` | The ID portion of an AWS access key. |
| `--target.kinesis.auth.creds.aws-secret-access-key` | The secret portion of an AWS access key. |
| `--target.kinesis.auth.role.role-arn` | An ARN that specifies the role that ngrok should use to deliver to the configured target. |
| `--target.kinesis.stream-arn` | An Amazon Resource Name specifying the Kinesis stream to deposit events into. |
| `--verify-with-test-event` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-sources
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-event-sources-create) | Add an additional type for which this event... |
| [delete](#ngrok-api-event-sources-delete) | Remove a type for which this event... |
| [get](#ngrok-api-event-sources-get) | Get the details for a given type that triggers... |
| [list](#ngrok-api-event-sources-list) | List the types for which this event... |
| [update](#ngrok-api-event-sources-update) | Update the type for which this event... |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-sources create
Add an additional type for which this event subscription will trigger
### Usage
```sh theme={null}
ngrok api event-sources create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--fields` | |
| `--filter` | |
| `--subscription-id` | The unique identifier for the Event Subscription that this Event Source is attached to. |
| `--type` | Type of event for which an event subscription will trigger |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-sources delete
Remove a type for which this event subscription will trigger
### Usage
```sh theme={null}
ngrok api event-sources delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--subscription-id` | The unique identifier for the Event Subscription that this Event Source is attached to. |
| `--type` | Type of event for which an event subscription will trigger |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-sources get
Get the details for a given type that triggers for the given event subscription
### Usage
```sh theme={null}
ngrok api event-sources get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--subscription-id` | The unique identifier for the Event Subscription that this Event Source is attached to. |
| `--type` | Type of event for which an event subscription will trigger |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-sources list
List the types for which this event subscription will trigger
### Usage
```sh theme={null}
ngrok api event-sources list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-sources update
Update the type for which this event subscription will trigger
### Usage
```sh theme={null}
ngrok api event-sources update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--fields` | |
| `--filter` | |
| `--subscription-id` | The unique identifier for the Event Subscription that this Event Source is attached to. |
| `--type` | Type of event for which an event subscription will trigger |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-subscriptions
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-event-subscriptions-create) | Create an Event Subscription. |
| [delete](#ngrok-api-event-subscriptions-delete) | Delete an Event Subscription. |
| [get](#ngrok-api-event-subscriptions-get) | Get an Event Subscription by ID. |
| [list](#ngrok-api-event-subscriptions-list) | List this Account's Event Subscriptions. |
| [update](#ngrok-api-event-subscriptions-update) | Update an Event Subscription. |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-subscriptions create
Create an Event Subscription.
### Usage
```sh theme={null}
ngrok api event-subscriptions create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | Arbitrary customer supplied information intended to be human readable. Optional, max 255 chars. |
| `--destination-ids` | A list of Event Destination IDs which should be used for this Event Subscription. |
| `--metadata` | Arbitrary customer supplied information intended to be machine readable. Optional, max 4096 chars. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-subscriptions delete
Delete an Event Subscription.
### Usage
```sh theme={null}
ngrok api event-subscriptions delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-subscriptions get
Get an Event Subscription by ID.
### Usage
```sh theme={null}
ngrok api event-subscriptions get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-subscriptions list
List this Account's Event Subscriptions.
### Usage
```sh theme={null}
ngrok api event-subscriptions list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | Expects a resource ID as its input. Returns earlier entries in the result set, sorted by ID. |
| `--filter` | A CEL expression to filter the list results. Supports logical and comparison operators to match on fields such as id, metadata, created\_at, and more. See ngrok API Filtering for syntax and field details: [https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering) ([https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering)). |
| `--limit` | Constrains the number of results in the dataset. See the API Overview ([https://ngrok.com/docs/api/index#pagination](https://ngrok.com/docs/api/index#pagination)) for details. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api event-subscriptions update
Update an Event Subscription.
### Usage
```sh theme={null}
ngrok api event-subscriptions update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | Arbitrary customer supplied information intended to be human readable. Optional, max 255 chars. |
| `--destination-ids` | A list of Event Destination IDs which should be used for this Event Subscription. |
| `--metadata` | Arbitrary customer supplied information intended to be machine readable. Optional, max 4096 chars. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policies
IP Policies are reusable groups of CIDR ranges with an allow or deny
action. They can be attached to endpoints via the Endpoint Configuration IP
Policy module. They can also be used with IP Restrictions to control source
IP ranges that can start tunnel sessions and connect to the API and dashboard.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-ip-policies-create) | Create a new IP policy |
| [delete](#ngrok-api-ip-policies-delete) | Delete an IP policy |
| [get](#ngrok-api-ip-policies-get) | Get detailed information about an IP policy by ID |
| [list](#ngrok-api-ip-policies-list) | List all IP policies on this account |
| [update](#ngrok-api-ip-policies-update) | Update attributes of an IP policy by ID |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policies create
Create a new IP policy. It will not apply to any traffic until you associate to a traffic source via an endpoint configuration or IP restriction.
### Usage
```sh theme={null}
ngrok api ip-policies create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--action` | this field is deprecated. Please leave it empty and use the ip policy rule object's "action" field instead. It is temporarily retained for backwards compatibility reasons. |
| `--description` | human-readable description of the source IPs of this IP policy. optional, max 255 bytes. |
| `--metadata` | arbitrary user-defined machine-readable data of this IP policy. optional, max 4096 bytes. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policies delete
Delete an IP policy. If the IP policy is referenced by another object for the purposes of traffic restriction it will be treated as if the IP policy remains but has zero rules.
### Usage
```sh theme={null}
ngrok api ip-policies delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policies get
Get detailed information about an IP policy by ID.
### Usage
```sh theme={null}
ngrok api ip-policies get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policies list
List all IP policies on this account
### Usage
```sh theme={null}
ngrok api ip-policies list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | Expects a resource ID as its input. Returns earlier entries in the result set, sorted by ID. |
| `--filter` | A CEL expression to filter the list results. Supports logical and comparison operators to match on fields such as id, metadata, created\_at, and more. See ngrok API Filtering for syntax and field details: [https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering) ([https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering)). |
| `--limit` | Constrains the number of results in the dataset. See the API Overview ([https://ngrok.com/docs/api/index#pagination](https://ngrok.com/docs/api/index#pagination)) for details. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policies update
Update attributes of an IP policy by ID
### Usage
```sh theme={null}
ngrok api ip-policies update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of the source IPs of this IP policy. optional, max 255 bytes. |
| `--metadata` | arbitrary user-defined machine-readable data of this IP policy. optional, max 4096 bytes. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policy-rules
IP Policy Rules are the IPv4 or IPv6 CIDRs entries that
make up an IP Policy.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-ip-policy-rules-create) | Create a new IP policy rule attached to an IP... |
| [delete](#ngrok-api-ip-policy-rules-delete) | Delete an IP policy rule. |
| [get](#ngrok-api-ip-policy-rules-get) | Get detailed information about an IP policy... |
| [list](#ngrok-api-ip-policy-rules-list) | List all IP policy rules on this account |
| [update](#ngrok-api-ip-policy-rules-update) | Update attributes of an IP policy rule by ID |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policy-rules create
Create a new IP policy rule attached to an IP Policy.
### Usage
```sh theme={null}
ngrok api ip-policy-rules create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--action` | the action to apply to the policy rule, either allow or deny |
| `--cidr` | an IP or IP range specified in CIDR notation. IPv4 and IPv6 are both supported. |
| `--description` | human-readable description of the source IPs of this IP rule. optional, max 255 bytes. |
| `--ip-policy-id` | ID of the IP policy this IP policy rule will be attached to |
| `--metadata` | arbitrary user-defined machine-readable data of this IP policy rule. optional, max 4096 bytes. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policy-rules delete
Delete an IP policy rule.
### Usage
```sh theme={null}
ngrok api ip-policy-rules delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policy-rules get
Get detailed information about an IP policy rule by ID.
### Usage
```sh theme={null}
ngrok api ip-policy-rules get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policy-rules list
List all IP policy rules on this account
### Usage
```sh theme={null}
ngrok api ip-policy-rules list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | Expects a resource ID as its input. Returns earlier entries in the result set, sorted by ID. |
| `--filter` | A CEL expression to filter the list results. Supports logical and comparison operators to match on fields such as id, metadata, created\_at, and more. See ngrok API Filtering for syntax and field details: [https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering) ([https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering)). |
| `--limit` | Constrains the number of results in the dataset. See the API Overview ([https://ngrok.com/docs/api/index#pagination](https://ngrok.com/docs/api/index#pagination)) for details. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-policy-rules update
Update attributes of an IP policy rule by ID
### Usage
```sh theme={null}
ngrok api ip-policy-rules update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--cidr` | an IP or IP range specified in CIDR notation. IPv4 and IPv6 are both supported. |
| `--description` | human-readable description of the source IPs of this IP rule. optional, max 255 bytes. |
| `--metadata` | arbitrary user-defined machine-readable data of this IP policy rule. optional, max 4096 bytes. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-restrictions
An IP restriction is a restriction placed on the CIDRs that are allowed to
initiate traffic to a specific aspect of your ngrok account. An IP
restriction has a type which defines the ingress it applies to. IP
restrictions can be used to enforce the source IPs that can make API
requests, log in to the dashboard, start ngrok agents, and connect to your
public-facing endpoints.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-ip-restrictions-create) | Create a new IP restriction |
| [delete](#ngrok-api-ip-restrictions-delete) | Delete an IP restriction |
| [get](#ngrok-api-ip-restrictions-get) | Get detailed information about an IP restriction |
| [list](#ngrok-api-ip-restrictions-list) | List all IP restrictions on this account |
| [update](#ngrok-api-ip-restrictions-update) | Update attributes of an IP restriction by ID |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-restrictions create
Create a new IP restriction
### Usage
```sh theme={null}
ngrok api ip-restrictions create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of this IP restriction. optional, max 255 bytes. |
| `--enforced` | true if the IP restriction will be enforced. if false, only warnings will be issued |
| `--ip-policy-ids` | the set of IP policy identifiers that are used to enforce the restriction |
| `--metadata` | arbitrary user-defined machine-readable data of this IP restriction. optional, max 4096 bytes. |
| `--type` | the type of IP restriction. this defines what traffic will be restricted with the attached policies. four values are currently supported: dashboard, api, agent, and endpoints |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-restrictions delete
Delete an IP restriction
### Usage
```sh theme={null}
ngrok api ip-restrictions delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-restrictions get
Get detailed information about an IP restriction
### Usage
```sh theme={null}
ngrok api ip-restrictions get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-restrictions list
List all IP restrictions on this account
### Usage
```sh theme={null}
ngrok api ip-restrictions list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | Expects a resource ID as its input. Returns earlier entries in the result set, sorted by ID. |
| `--filter` | A CEL expression to filter the list results. Supports logical and comparison operators to match on fields such as id, metadata, created\_at, and more. See ngrok API Filtering for syntax and field details: [https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering) ([https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering)). |
| `--limit` | Constrains the number of results in the dataset. See the API Overview ([https://ngrok.com/docs/api/index#pagination](https://ngrok.com/docs/api/index#pagination)) for details. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api ip-restrictions update
Update attributes of an IP restriction by ID
### Usage
```sh theme={null}
ngrok api ip-restrictions update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of this IP restriction. optional, max 255 bytes. |
| `--enforced` | true if the IP restriction will be enforced. if false, only warnings will be issued |
| `--ip-policy-ids` | the set of IP policy identifiers that are used to enforce the restriction |
| `--metadata` | arbitrary user-defined machine-readable data of this IP restriction. optional, max 4096 bytes. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api kubernetes-operators
KubernetesOperators is used by the Kubernetes Operator to register and
manage its own resource, as well as for users to see active kubernetes
clusters.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-kubernetes-operators-create) | Create a new Kubernetes Operator |
| [delete](#ngrok-api-kubernetes-operators-delete) | Delete a Kubernetes Operator |
| [get](#ngrok-api-kubernetes-operators-get) | Get of a Kubernetes Operator |
| [get-bound-endpoints](#ngrok-api-kubernetes-operators-get-bound-endpoints) | List Endpoints bound to a Kubernetes Operator |
| [list](#ngrok-api-kubernetes-operators-list) | List all Kubernetes Operators owned by this... |
| [update](#ngrok-api-kubernetes-operators-update) | Update an existing Kubernetes operator by ID. |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api kubernetes-operators create
Create a new Kubernetes Operator
### Usage
```sh theme={null}
ngrok api kubernetes-operators create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--binding.csr` | CSR is supplied during initial creation to enable creating a mutual TLS secured connection between ngrok and the operator. This is an internal implementation detail and subject to change. |
| `--binding.endpoint-selectors` | the list of cel expressions that filter the k8s bound endpoints for this operator |
| `--binding.ingress-endpoint` | the public ingress endpoint for this Kubernetes Operator |
| `--deployment.cluster-name` | user-given name for the cluster the Kubernetes Operator is deployed to |
| `--deployment.name` | the deployment name |
| `--deployment.namespace` | the namespace this Kubernetes Operator is deployed to |
| `--deployment.version` | the version of this Kubernetes Operator |
| `--description` | human-readable description of this Kubernetes Operator. optional, max 255 bytes. |
| `--enabled-features` | features enabled for this Kubernetes Operator. a subset of "bindings", "ingress", and "gateway" |
| `--metadata` | arbitrary user-defined machine-readable data of this Kubernetes Operator. optional, max 4096 bytes. |
| `--region` | the ngrok region in which the ingress for this operator is served. defaults to "global" |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api kubernetes-operators delete
Delete a Kubernetes Operator
### Usage
```sh theme={null}
ngrok api kubernetes-operators delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api kubernetes-operators get
Get of a Kubernetes Operator
### Usage
```sh theme={null}
ngrok api kubernetes-operators get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api kubernetes-operators get-bound-endpoints
List Endpoints bound to a Kubernetes Operator
### Usage
```sh theme={null}
ngrok api kubernetes-operators get-bound-endpoints [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api kubernetes-operators list
List all Kubernetes Operators owned by this account
### Usage
```sh theme={null}
ngrok api kubernetes-operators list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api kubernetes-operators update
Update an existing Kubernetes operator by ID.
### Usage
```sh theme={null}
ngrok api kubernetes-operators update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--binding.csr` | CSR is supplied during initial creation to enable creating a mutual TLS secured connection between ngrok and the operator. This is an internal implementation detail and subject to change. |
| `--binding.endpoint-selectors` | the list of cel expressions that filter the k8s bound endpoints for this operator |
| `--binding.ingress-endpoint` | the public ingress endpoint for this Kubernetes Operator |
| `--deployment.name` | the deployment name |
| `--deployment.version` | the version of this Kubernetes Operator |
| `--description` | human-readable description of this Kubernetes Operator. optional, max 255 bytes. |
| `--enabled-features` | features enabled for this Kubernetes Operator. a subset of "bindings", "ingress", and "gateway" |
| `--metadata` | arbitrary user-defined machine-readable data of this Kubernetes Operator. optional, max 4096 bytes. |
| `--region` | the ngrok region in which the ingress for this operator is served. defaults to "global" |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks
Networks provide private address space for an account.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-networks-create) | Create a network |
| [delete](#ngrok-api-networks-delete) | Delete a network and its IP assignments. |
| [get](#ngrok-api-networks-get) | Get a network by ID. |
| [ips](#ngrok-api-networks-ips) | IP assignments reserve addresses in a network. |
| [list](#ngrok-api-networks-list) | List networks owned by the authenticated account. |
| [peers](#ngrok-api-networks-peers) | Peers are devices or processes with a current session in a network. They are read-only. |
| [update](#ngrok-api-networks-update) | Update the description or metadata |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks create
Create a network. Omitted CIDRs and the search domain receive defaults.
### Usage
```sh theme={null}
ngrok api networks create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | Optional human-readable description. |
| `--ipv-4-cidr` | Private IPv4 CIDR. If omitted, the API allocates an RFC 1918 /16. |
| `--ipv-6-cidr` | Private IPv6 CIDR. If omitted, the API allocates a /56 within the account's unique-local /48. |
| `--metadata` | User-defined metadata as string key-value pairs. |
| `--search-domain` | DNS suffix without a leading dot. Defaults to the network ID, with its underscore replaced by a hyphen, under ngrok.network. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks delete
Delete a network and its IP assignments.
### Usage
```sh theme={null}
ngrok api networks delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks get
Get a network by ID.
### Usage
```sh theme={null}
ngrok api networks get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks ips
IP assignments reserve addresses in a network.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-networks-ips-create) | Reserve a static IP address in a network. |
| [delete](#ngrok-api-networks-ips-delete) | Release an IP assignment. |
| [get](#ngrok-api-networks-ips-get) | Get an IP assignment by ID within its network. |
| [list](#ngrok-api-networks-ips-list) | List IP assignments in a network. |
| [update](#ngrok-api-networks-ips-update) | Update an assignment's name |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks ips create
Reserve a static IP address in a network.
### Usage
```sh theme={null}
ngrok api networks ips create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--address` | Requested address within the network's CIDR. If omitted, the API allocates an address. |
| `--ip-version` | Address family: 4 or 6. Required without an address. If both are present, they must match. |
| `--name` | Optional DNS label, unique per address family within the network. Names are case-insensitive and returned in lowercase. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks ips delete
Release an IP assignment.
### Usage
```sh theme={null}
ngrok api networks ips delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks ips get
Get an IP assignment by ID within its network.
### Usage
```sh theme={null}
ngrok api networks ips get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks ips list
List IP assignments in a network.
### Usage
```sh theme={null}
ngrok api networks ips list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks ips update
Update an assignment's name. An empty string clears the name.
### Usage
```sh theme={null}
ngrok api networks ips update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--name` | Optional DNS label, unique per address family within the network. Names are case-insensitive and returned in lowercase. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks list
List networks owned by the authenticated account.
### Usage
```sh theme={null}
ngrok api networks list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks peers
Peers are devices or processes with a current session in a network. They are read-only.
### SubCommands
| Command | Description |
| - | - |
| [get](#ngrok-api-networks-peers-get) | Get a peer by ID within its network. |
| [list](#ngrok-api-networks-peers-list) | List peers in a network. |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks peers get
Get a peer by ID within its network.
### Usage
```sh theme={null}
ngrok api networks peers get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks peers list
List peers in a network.
### Usage
```sh theme={null}
ngrok api networks peers list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | |
| `--limit` | |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api networks update
Update the description or metadata. An empty string clears the description. An empty map clears metadata.
### Usage
```sh theme={null}
ngrok api networks update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | Optional human-readable description. |
| `--metadata` | User-defined metadata as string key-value pairs. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api personal-access-tokens
Personal Access Tokens (PATs) are bearer credentials that authenticate the
ngrok agent as the issuing principal. The token secret is only returned at
creation time; save it securely. A PAT can use only its scopes, and only
while the principal's current role in the account still grants them.
### SubCommands
| Command | Description |
| - | - |
| [create](#ngrok-api-personal-access-tokens-create) | Create a new Personal Access Token |
| [delete](#ngrok-api-personal-access-tokens-delete) | Delete a Personal Access Token by ID |
| [get](#ngrok-api-personal-access-tokens-get) | Get a Personal Access Token by ID. |
| [list](#ngrok-api-personal-access-tokens-list) | List all Personal Access Tokens for this account |
| [revoke](#ngrok-api-personal-access-tokens-revoke) | Revoke a Personal Access Token by ID |
| [update](#ngrok-api-personal-access-tokens-update) | Update attributes of a Personal Access Token... |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api personal-access-tokens create
Create a new Personal Access Token. The token secret is only returned in this response and cannot be retrieved later. If lost, you must create a new token.
### Usage
```sh theme={null}
ngrok api personal-access-tokens create [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of this token. Optional, max 255 bytes. |
| `--expires-at` | optional expiration time for this token. If unset the token does not expire. |
| `--scopes` | scopes this token can use, e.g. \["endpoints:read"]. Each must be a scope you can grant. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api personal-access-tokens delete
Delete a Personal Access Token by ID. The token immediately stops working and disappears from Get/List, but is not permanently removed -- it may be restored by an ngrok operator as part of a support request.
### Usage
```sh theme={null}
ngrok api personal-access-tokens delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api personal-access-tokens get
Get a Personal Access Token by ID.
### Usage
```sh theme={null}
ngrok api personal-access-tokens get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api personal-access-tokens list
List all Personal Access Tokens for this account
### Usage
```sh theme={null}
ngrok api personal-access-tokens list [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--before-id` | Expects a resource ID as its input. Returns earlier entries in the result set, sorted by ID. |
| `--filter` | A CEL expression to filter the list results. Supports logical and comparison operators to match on fields such as id, metadata, created\_at, and more. See ngrok API Filtering for syntax and field details: [https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering) ([https://ngrok.com/docs/api/api-filtering](https://ngrok.com/docs/api/api-filtering)). |
| `--limit` | Constrains the number of results in the dataset. See the API Overview ([https://ngrok.com/docs/api/index#pagination](https://ngrok.com/docs/api/index#pagination)) for details. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api personal-access-tokens revoke
Revoke a Personal Access Token by ID. Unlike Delete, a revoked token remains visible in Get/List responses.
### Usage
```sh theme={null}
ngrok api personal-access-tokens revoke [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api personal-access-tokens update
Update attributes of a Personal Access Token by ID.
### Usage
```sh theme={null}
ngrok api personal-access-tokens update [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--description` | human-readable description of this token. Optional, max 255 bytes. |
| `--scopes` | replaces the token's scopes. Omit to keep them. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module
### SubCommands
| Command | Description |
| - | - |
| [backend](#ngrok-api-pointcfg-module-backend) | |
| [basic-auth](#ngrok-api-pointcfg-module-basic-auth) | |
| [circuit-breaker](#ngrok-api-pointcfg-module-circuit-breaker) | |
| [compression](#ngrok-api-pointcfg-module-compression) | |
| [ip-policy](#ngrok-api-pointcfg-module-ip-policy) | |
| [mutual-tls](#ngrok-api-pointcfg-module-mutual-tls) | |
| [oauth](#ngrok-api-pointcfg-module-oauth) | |
| [oidc](#ngrok-api-pointcfg-module-oidc) | |
| [request-headers](#ngrok-api-pointcfg-module-request-headers) | |
| [response-headers](#ngrok-api-pointcfg-module-response-headers) | |
| [saml](#ngrok-api-pointcfg-module-saml) | |
| [tls-termination](#ngrok-api-pointcfg-module-tls-termination) | |
| [webhook-validation](#ngrok-api-pointcfg-module-webhook-validation) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module backend
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-pointcfg-module-backend-delete) | |
| [get](#ngrok-api-pointcfg-module-backend-get) | |
| [replace](#ngrok-api-pointcfg-module-backend-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module backend delete
### Usage
```sh theme={null}
ngrok api pointcfg-module backend delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module backend get
### Usage
```sh theme={null}
ngrok api pointcfg-module backend get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module backend replace
### Usage
```sh theme={null}
ngrok api pointcfg-module backend replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.backend-id` | backend to be used to back this endpoint |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module basic-auth
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-pointcfg-module-basic-auth-delete) | |
| [get](#ngrok-api-pointcfg-module-basic-auth-get) | |
| [replace](#ngrok-api-pointcfg-module-basic-auth-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module basic-auth delete
### Usage
```sh theme={null}
ngrok api pointcfg-module basic-auth delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module basic-auth get
### Usage
```sh theme={null}
ngrok api pointcfg-module basic-auth get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module basic-auth replace
### Usage
```sh theme={null}
ngrok api pointcfg-module basic-auth replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.allow-options` | true or false indicating whether to allow OPTIONS requests through without authentication which is necessary for CORS. default is false |
| `--module.auth-provider-id` | determines how the basic auth credentials are validated. Currently only the value agent is supported which means that credentials will be validated against the username and password specified by the ngrok agent's --basic-auth flag, if any. |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.realm` | an arbitrary string to be specified in as the 'realm' value in the WWW-Authenticate header. default is ngrok |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module circuit-breaker
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-pointcfg-module-circuit-breaker-delete) | |
| [get](#ngrok-api-pointcfg-module-circuit-breaker-get) | |
| [replace](#ngrok-api-pointcfg-module-circuit-breaker-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module circuit-breaker delete
### Usage
```sh theme={null}
ngrok api pointcfg-module circuit-breaker delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module circuit-breaker get
### Usage
```sh theme={null}
ngrok api pointcfg-module circuit-breaker get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module circuit-breaker replace
### Usage
```sh theme={null}
ngrok api pointcfg-module circuit-breaker replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.error-threshold-percentage` | Error threshold percentage should be between 0 - 1.0, not 0-100.0 |
| `--module.num-buckets` | Integer number of buckets into which metrics are retained. Max 128. |
| `--module.rolling-window` | Integer number of seconds in the statistical rolling window that metrics are retained for. |
| `--module.tripped-duration` | Integer number of seconds after which the circuit is tripped to wait before re-evaluating upstream health |
| `--module.volume-threshold` | Integer number of requests in a rolling window that will trip the circuit. Helpful if traffic volume is low. |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module compression
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-pointcfg-module-compression-delete) | |
| [get](#ngrok-api-pointcfg-module-compression-get) | |
| [replace](#ngrok-api-pointcfg-module-compression-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module compression delete
### Usage
```sh theme={null}
ngrok api pointcfg-module compression delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module compression get
### Usage
```sh theme={null}
ngrok api pointcfg-module compression get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module compression replace
### Usage
```sh theme={null}
ngrok api pointcfg-module compression replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module ip-policy
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-pointcfg-module-ip-policy-delete) | |
| [get](#ngrok-api-pointcfg-module-ip-policy-get) | |
| [replace](#ngrok-api-pointcfg-module-ip-policy-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module ip-policy delete
### Usage
```sh theme={null}
ngrok api pointcfg-module ip-policy delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module ip-policy get
### Usage
```sh theme={null}
ngrok api pointcfg-module ip-policy get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module ip-policy replace
### Usage
```sh theme={null}
ngrok api pointcfg-module ip-policy replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--module.ip-policy-ids` | list of all IP policies that will be used to check if a source IP is allowed access to the endpoint |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module mutual-tls
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-pointcfg-module-mutual-tls-delete) | |
| [get](#ngrok-api-pointcfg-module-mutual-tls-get) | |
| [replace](#ngrok-api-pointcfg-module-mutual-tls-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module mutual-tls delete
### Usage
```sh theme={null}
ngrok api pointcfg-module mutual-tls delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module mutual-tls get
### Usage
```sh theme={null}
ngrok api pointcfg-module mutual-tls get [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module mutual-tls replace
### Usage
```sh theme={null}
ngrok api pointcfg-module mutual-tls replace [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--module.certificate-authority-ids` | list of certificate authorities that will be used to validate the TLS client certificate presented by the initiator of the TLS connection |
| `--module.enabled` | true if the module will be applied to traffic, false to disable. default true if unspecified |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module oauth
### SubCommands
| Command | Description |
| - | - |
| [delete](#ngrok-api-pointcfg-module-oauth-delete) | |
| [get](#ngrok-api-pointcfg-module-oauth-get) | |
| [replace](#ngrok-api-pointcfg-module-oauth-replace) | |
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module oauth delete
### Usage
```sh theme={null}
ngrok api pointcfg-module oauth delete [flags]
```
### Flags
| Flag | Description |
| - | - |
| `--api-key` | API key to use |
| `--config` | path to config files; they are merged if multiple |
| `--log` | path to log file, 'stdout', 'stderr' or 'false' |
| `--log-format` | log record format: 'term', 'logfmt', 'json' |
| `--log-level` | logging level: 'debug', 'info', 'warn', 'error', 'crit' |
## ngrok api pointcfg-module oauth get
### Usage
```sh theme={null}
ngrok api pointcfg-module oauth get