mirror of
https://github.com/remnawave/panel.git
synced 2026-04-12 17:24:16 +00:00
* chore: change link to docs. * docs: add Go SDK documentation * up rwp shop. * feat: add private link handling. * docs: update Go SDK documentation for v2.6.1 - Add v2.6.1 and v2.5.3 to version table - Update type names: remove Dto suffix (CreateUserRequestDto → CreateUserRequest) - Add pagination example with PaginationHelper - Update controllers list: 14 → 26 controllers - Add new features: OpenTelemetry, RequestOption, Editors - Fix error handling example to match actual Res interfaces
8.7 KiB
8.7 KiB
sidebar_position, title
| sidebar_position | title |
|---|---|
| 4 | Go SDK [community] |
import Admonition from '@theme/Admonition'; import { FaPeopleGroup } from "react-icons/fa6";
<Admonition type="note" icon={} title="Community SDK"> This SDK is fully community-maintained.
Remnawave Go SDK is a library for convenient interaction with the RestAPI.
✨ Key Features
- Generated with ogen v1.19.0: Zero-reflection JSON decoder for high throughput
- Type-safe: Compile-time validation against OpenAPI 3.0 spec
- Controller-based design: Organized sub-clients for clean API access
- Simplified signatures: No verbose Params structs for simple operations
- Context support: First-class
context.Contextsupport - OpenTelemetry: Built-in tracing instrumentation
- Request options: Per-request customization via
...RequestOption - Editors: Request/response middleware support
Installation
go get github.com/Jolymmiles/remnawave-api-go/v2@latest
:::warning Always pick and pin the correct version of the SDK to match the version of the Remnawave backend. :::
| SDK Version | Remnawave Panel Version |
|---|---|
| v2.6.1 | 2.6.1 |
| v2.5.3 | 2.5.3 |
| v2.3.0-6 | 2.3.0 |
| v2.2.6-3 | 2.2.6 |
Usage
Basic example
package main
import (
"context"
"fmt"
"log"
remapi "github.com/Jolymmiles/remnawave-api-go/v2/api"
)
func main() {
ctx := context.Background()
// Create base client
baseClient, err := remapi.NewClient(
"https://your-panel.example.com",
remapi.StaticToken{Token: "YOUR_API_TOKEN"},
)
if err != nil {
log.Fatal(err)
}
// Wrap with organized sub-clients
client := remapi.NewClientExt(baseClient)
// Get user by UUID - simplified signature
resp, err := client.Users().GetUserByUuid(ctx, "user-uuid-here")
if err != nil {
log.Fatal(err)
}
switch r := resp.(type) {
case *remapi.UserResponse:
fmt.Printf("User: %s\n", r.Response.Username)
case *remapi.NotFoundError:
fmt.Println("User not found")
case *remapi.BadRequestError:
fmt.Printf("Validation error: %v\n", r.Errors)
}
}
Create and manage users
package main
import (
"context"
"fmt"
"log"
remapi "github.com/Jolymmiles/remnawave-api-go/v2/api"
)
func main() {
ctx := context.Background()
baseClient, _ := remapi.NewClient(
"https://your-panel.example.com",
remapi.StaticToken{Token: "YOUR_API_TOKEN"},
)
client := remapi.NewClientExt(baseClient)
// Create user
createResp, err := client.Users().CreateUser(ctx, &remapi.CreateUserRequest{
Username: "john_doe",
})
if err != nil {
log.Fatal(err)
}
user := createResp.(*remapi.UserResponse).Response
fmt.Printf("Created user: %s (UUID: %s)\n", user.Username, user.UUID)
// Disable user
_, err = client.Users().DisableUser(ctx, user.UUID.String())
if err != nil {
log.Fatal(err)
}
fmt.Println("User disabled")
// Enable user
_, err = client.Users().EnableUser(ctx, user.UUID.String())
if err != nil {
log.Fatal(err)
}
fmt.Println("User enabled")
// Delete user
_, err = client.Users().DeleteUser(ctx, user.UUID.String())
if err != nil {
log.Fatal(err)
}
fmt.Println("User deleted")
}
Node management
package main
import (
"context"
"fmt"
"log"
remapi "github.com/Jolymmiles/remnawave-api-go/v2/api"
)
func main() {
ctx := context.Background()
baseClient, _ := remapi.NewClient(
"https://your-panel.example.com",
remapi.StaticToken{Token: "YOUR_API_TOKEN"},
)
client := remapi.NewClientExt(baseClient)
// Get all nodes
nodesResp, err := client.Nodes().GetAllNodes(ctx)
if err != nil {
log.Fatal(err)
}
nodes := nodesResp.(*remapi.NodesResponse).Response
fmt.Printf("Total nodes: %d\n", len(nodes))
for _, node := range nodes {
fmt.Printf(" - %s (%s): connected=%v\n",
node.Name, node.Address, node.IsConnected)
}
// Get single node
if len(nodes) > 0 {
nodeResp, _ := client.Nodes().GetOneNode(ctx, nodes[0].UUID.String())
node := nodeResp.(*remapi.NodeResponse).Response
fmt.Printf("\nNode details: %s\n", node.Name)
}
}
Pagination
package main
import (
"context"
"fmt"
"log"
remapi "github.com/Jolymmiles/remnawave-api-go/v2/api"
)
func main() {
ctx := context.Background()
baseClient, _ := remapi.NewClient(
"https://your-panel.example.com",
remapi.StaticToken{Token: "YOUR_API_TOKEN"},
)
client := remapi.NewClientExt(baseClient)
// Use PaginationHelper for iterating through pages
pager := remapi.NewPaginationHelper(50) // 50 items per page
for pager.HasMore {
resp, err := client.Users().GetAllUsers(ctx,
pager.Limit, // size
pager.Offset, // start
)
if err != nil {
log.Fatal(err)
}
users := resp.(*remapi.GetAllUsersResponse)
for _, user := range users.Response.Users {
fmt.Printf("User: %s (UUID: %s)\n", user.Username, user.UUID)
}
// Advance to next page
pager.SetTotal(int(users.Response.Total))
pager.NextPage()
}
fmt.Printf("Total users: %d\n", *pager.Total)
}
Error handling
package main
import (
"context"
"fmt"
"log"
remapi "github.com/Jolymmiles/remnawave-api-go/v2/api"
)
func main() {
ctx := context.Background()
baseClient, _ := remapi.NewClient(
"https://your-panel.example.com",
remapi.StaticToken{Token: "YOUR_API_TOKEN"},
)
client := remapi.NewClientExt(baseClient)
resp, err := client.Users().GetUserByUuid(ctx, "invalid-uuid")
if err != nil {
log.Fatal("Network error:", err)
}
// Available error types depend on the endpoint — check the generated
// Res interface (e.g. UsersGetUserByUuidRes) for the full list.
switch e := resp.(type) {
case *remapi.UserResponse:
fmt.Printf("User found: %s\n", e.Response.Username)
case *remapi.BadRequestError:
fmt.Println("Validation errors:")
for _, ve := range e.Errors {
fmt.Printf(" - %s: %s (path: %v)\n",
ve.Code, ve.Message, ve.Path)
}
case *remapi.NotFoundError:
fmt.Println("Resource not found")
case *remapi.InternalServerError:
fmt.Printf("Server error: %s\n", e.Message.Value)
}
}
Available Controllers
| Controller | Description |
|---|---|
client.ApiTokens() |
API token management |
client.Auth() |
Authentication |
client.BandwidthStatsNodes() |
Node bandwidth statistics |
client.BandwidthStatsUsers() |
User bandwidth statistics |
client.ConfigProfile() |
Config profiles |
client.ExternalSquad() |
External squads |
client.Hosts() |
Host management |
client.HostsBulkActions() |
Bulk host operations |
client.HwidUserDevices() |
HWID devices |
client.InfraBilling() |
Infrastructure billing |
client.InternalSquad() |
Internal squads |
client.Keygen() |
Key generation |
client.Nodes() |
Node management |
client.NodesUsageHistory() |
Node usage history |
client.Passkey() |
Passkey authentication |
client.RemnawaveSettings() |
Panel settings |
client.Snippets() |
Code snippets |
client.Subscription() |
Subscription management |
client.SubscriptionPageConfig() |
Subscription page config |
client.SubscriptionSettings() |
Subscription settings |
client.SubscriptionTemplate() |
Subscription templates |
client.Subscriptions() |
Multiple subscriptions |
client.System() |
System info |
client.UserSubscriptionRequestHistory() |
Request history |
client.Users() |
User management |
client.UsersBulkActions() |
Bulk user operations |
Error Types
| Type | HTTP Status | Description |
|---|---|---|
BadRequestError |
400 | Validation errors with details |
UnauthorizedError |
401 | Authentication required |
ForbiddenError |
403 | Access denied |
NotFoundError |
404 | Resource not found |
InternalServerError |
500 | Server error |
🛠️ Project Links
- GitHub Repository: remnawave-api-go on GitHub
- Author: Jolymmiles