Documentation / API Reference

API Reference

Create and manage tunnels programmatically with the stunl gRPC API

Overview

stunl exposes two APIs. The gRPC API is what the stunl CLI and SDKs use for low-latency streaming — tunnel lifecycle, request/response framing, real-time events. The REST API at api.stunl.com is for everything else: account management, tunnel CRUD, webhooks, Inspector captures, and integrations from any HTTPS-capable client.

Connection Details
REST API base URL https://api.stunl.com
gRPC server portal.stunl.com:9090
Protocol HTTPS (REST) / gRPC over TLS
Authentication Authorization: Bearer <token> (REST) / API key in x-api-key metadata (gRPC)

Proto Files

The complete protobuf definitions are available at stunl.com-proto

REST API

The REST API at https://api.stunl.com is OpenAPI-compatible and works from any HTTPS client. Responses are JSON; sensitive data uses Cache-Control: no-store. All endpoints (except /health and /api/version) require an Authorization: Bearer <token> header.

Health check — no auth required
$ curl https://api.stunl.com/health
{"status":"healthy"}
Service version — public, useful for client compatibility checks
$ curl https://api.stunl.com/api/version
{"service":"portal","version":"5.35.0","git_sha":"abc1234"}
Login — exchange email + password for a JWT
$ curl -X POST https://api.stunl.com/api/auth/login \
    -H "Content-Type: application/json" \
    -d '{"email":"you@example.com","password":"hunter2"}'
{"access_token":"eyJ…","refresh_token":"eyJ…","expires_in":3600}
Authenticated request — pass the JWT in the Authorization header
$ curl https://api.stunl.com/api/account \
    -H "Authorization: Bearer $TOKEN"

Notes

  • Admin endpoints (/api/admin/*) are not exposed on api.stunl.com — they live on portal.stunl.com and require admin auth.
  • Rate limits: 10 req/sec per IP on most endpoints, 1 req/sec on auth/login/register endpoints (brute-force protection).
  • The /v1/… versioned path prefix is reserved for the next major API revision; today everything lives under /api/… on both api.stunl.com and portal.stunl.com.

gRPC Authentication

For the gRPC API, include your API key in the metadata.

Authentication (Go example)
import (
    "google.golang.org/grpc"
    "google.golang.org/grpc/metadata"
)

// Create gRPC connection with API key
func connectWithAuth(apiKey string) (*grpc.ClientConn, error) {
    // Add API key to context
    ctx := metadata.AppendToOutgoingContext(
        context.Background(),
        "x-api-key", apiKey,
    )
    
    conn, err := grpc.DialContext(ctx,
        "portal.stunl.com:9090",
        grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
    )
    return conn, err
}

gRPC Services

Service Purpose
AuthService Authentication, API key validation, session management
TunnelService Tunnel lifecycle (create, destroy, list)
HTTPTunnelService HTTP request/response streaming
TCPTunnelService TCP data streaming
UDPTunnelService UDP packet forwarding
ManagementService Health checks, metrics, admin operations
OAuthService OAuth provider integration

TunnelService

The main service for creating and managing tunnels.

CreateTunnel

Create a new tunnel and establish connection.

CreateTunnelRequest
message CreateTunnelRequest {
  string      tunnel_id = 1;       // Custom tunnel ID (optional)
  TunnelType  tunnel_type = 2;     // HTTP, TCP, UDP
  int32       local_port = 3;      // Local port to tunnel
  string      local_host = 4;      // Local host (default: localhost)
  string      domain = 5;          // Custom domain (optional)
  bool        use_root_domain = 6; // Use root domain
  string      password = 7;        // Basic auth password
  int32       preferred_port = 8;  // Reserved public port
  TunnelOAuthConfig oauth = 9;   // OAuth configuration
}
CreateTunnelResponse
message CreateTunnelResponse {
  string     tunnel_id = 1;     // Assigned tunnel ID
  string     public_url = 2;    // Public HTTPS URL
  string     public_addr = 3;   // Public hostname
  int32      public_port = 4;   // Public port (for TCP/UDP)
  TunnelType tunnel_type = 5;  // Tunnel type
  int32      local_port = 6;    // Local port
}

TunnelType Enum

enum TunnelType {
  TUNNEL_TYPE_UNSPECIFIED = 0;
  TUNNEL_TYPE_HTTP = 1;
  TUNNEL_TYPE_TCP = 2;
  TUNNEL_TYPE_UDP = 3;
  TUNNEL_TYPE_WEBSOCKET = 4;
}

DestroyTunnel

Terminate an active tunnel.

message DestroyTunnelRequest {
  string tunnel_id = 1;
}

message DestroyTunnelResponse {
  bool success = 1;
  string message = 2;
}

ListTunnels

List all active tunnels for the authenticated user.

message ListTunnelsRequest {}

message ListTunnelsResponse {
  repeated TunnelInfo tunnels = 1;
}

message TunnelInfo {
  string     tunnel_id = 1;
  string     public_url = 2;
  TunnelType tunnel_type = 3;
  int32      local_port = 4;
  int64      created_at = 5;
  int64      bytes_in = 6;
  int64      bytes_out = 7;
}

OAuth Configuration

Configure OAuth authentication for your tunnels.

TunnelOAuthConfig
message TunnelOAuthConfig {
  AuthProvider provider = 1;            // OAuth provider
  repeated string allowed_domains = 2;  // Email domain whitelist
  repeated string allowed_emails = 3;   // Specific email whitelist
  repeated string github_orgs = 4;      // GitHub org restrictions
  repeated string github_teams = 5;     // GitHub team restrictions
}

enum AuthProvider {
  AUTH_PROVIDER_UNSPECIFIED = 0;
  AUTH_PROVIDER_GITHUB = 1;
  AUTH_PROVIDER_GOOGLE = 2;
  AUTH_PROVIDER_MICROSOFT = 3;
}

Data Streaming

Once a tunnel is created, data flows through bidirectional gRPC streams.

HTTPTunnelService
service HTTPTunnelService {
  // Bidirectional stream for HTTP requests/responses
  rpc StreamHTTP(stream HTTPRequest) returns (stream HTTPResponse);
}

message HTTPRequest {
  string request_id = 1;
  string method = 2;
  string path = 3;
  map<string, string> headers = 4;
  bytes body = 5;
}

message HTTPResponse {
  string request_id = 1;
  int32 status_code = 2;
  map<string, string> headers = 3;
  bytes body = 4;
}
TCPTunnelService
service TCPTunnelService {
  // Bidirectional stream for raw TCP data
  rpc StreamTCP(stream TCPData) returns (stream TCPData);
}

message TCPData {
  string connection_id = 1;
  bytes data = 2;
  bool eof = 3;
}

Error Handling

The API uses standard gRPC status codes with additional error details.

Code Meaning
UNAUTHENTICATED Invalid or missing API key
PERMISSION_DENIED Feature not available in your tier
RESOURCE_EXHAUSTED Tunnel or bandwidth limit exceeded
ALREADY_EXISTS Tunnel ID already in use
NOT_FOUND Tunnel not found
UNAVAILABLE Server temporarily unavailable

Rate Limits

Operation Pro
CreateTunnel / min 30
API requests / min 200
Concurrent connections 20

Client Libraries

Official and community client libraries are available:

Related Documentation