Create and manage tunnels programmatically with the stunl gRPC API
stunl uses gRPC for client-server communication. This allows you to build custom clients, integrate tunneling into your applications, or automate tunnel management.
| Server | grpc.stunl.com:9090 |
| Protocol | gRPC over TLS |
| Authentication | API Key (metadata header) |
Proto Files
The complete protobuf definitions are available at stunl.com-proto
Include your API key in the gRPC metadata for authentication.
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,
"grpc.stunl.com:9090",
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
)
return conn, err
}
| 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 |
The main service for creating and managing tunnels.
Create a new tunnel and establish connection.
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
}
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
}
enum TunnelType {
TUNNEL_TYPE_UNSPECIFIED = 0;
TUNNEL_TYPE_HTTP = 1;
TUNNEL_TYPE_TCP = 2;
TUNNEL_TYPE_UDP = 3;
TUNNEL_TYPE_WEBSOCKET = 4;
}
Terminate an active tunnel.
message DestroyTunnelRequest {
string tunnel_id = 1;
}
message DestroyTunnelResponse {
bool success = 1;
string message = 2;
}
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;
}
Configure OAuth authentication for your tunnels.
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;
}
Once a tunnel is created, data flows through bidirectional gRPC streams.
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;
}
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;
}
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 |
| Operation | Pro |
|---|---|
| CreateTunnel / min | 30 |
| API requests / min | 600 |
| Concurrent connections | 100 |
Official and community client libraries are available: