How to Use the AxonHub GraphQL API for Management Operations

AxonHub exposes a single GraphQL endpoint at /openapi/v1/graphql that provides type-safe, RBAC-protected management operations for channels, API keys, users, roles, and projects, implemented via gqlgen and wired into the Gin HTTP server.

The looplj/axonhub repository provides a comprehensive management interface through its GraphQL API. This endpoint allows administrators to programmatically control every aspect of the platform, from provisioning AI model channels to managing user permissions, all through a strongly-typed schema defined in the source code.

Architecture of the GraphQL Management API

GraphQL Schema Definition

All public mutations and queries live in internal/server/gql/axonhub.graphql. The type Mutation definition lists every management operation, including createChannel, bulkCreateChannels, deleteChannel, disableChannelAPIKey, createUser, and updateProject. These definitions enforce input validation and type safety at the API boundary.

Source: internal/server/gql/axonhub.graphql

Resolver Implementation

Each schema field is backed by a resolver in internal/server/gql/axonhub.resolvers.go. These resolvers act as the bridge between the GraphQL layer and the business logic. For example, the CreateChannel resolver calls r.channelService.CreateChannel to persist the new channel and returns the result to the client.

Source: [internal/server/gql/axonhub.resolvers.go](https://github.com/looplj/axonhub/blob/unstable/internal/server/gql/axonhub.resolvers.go)

Business Logic Layer

The core operations are implemented in the internal/server/biz/ directory. Services such as ChannelService, APIKeyService, UserService, and ProjectService handle validation, database persistence via Ent, and side effects.

Sources:

Authentication and Authorization

Management calls require a valid JWT. Users obtain a token via the POST /auth/signin HTTP route, handled by internal/server/api/auth.go. The token must be sent as an Authorization: Bearer <token> header on every GraphQL request. The Gin router applies middleware to enforce this protection.

Sources:

GraphQL Endpoint and Authentication

The management GraphQL API is exposed at /openapi/v1/graphql. All requests must include a Bearer token in the Authorization header.

First, obtain a JWT token:

curl -X POST http://localhost:8090/auth/signin \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@example.com","password":"your‑password"}'

The response contains:

{
  "user": { "id": 1, "email": "admin@example.com" },
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Management Operations Examples

Creating a Channel

Use the createChannel mutation to provision a new AI model channel. This delegates to the channel service in internal/server/biz/channel.go.

TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI…"

curl -X POST http://localhost:8090/openapi/v1/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "query": "mutation CreateChannel($input: CreateChannelInput!) { createChannel(input: $input) { id name type status } }",
    "variables": {
      "input": {
        "type": "OPENAI",
        "name": "my-openai-channel",
        "tags": ["production"],
        "baseURL": "https://api.openai.com/v1",
        "apiKeys": ["sk-xxxx"],
        "supportedModels": ["gpt-4o"],
        "defaultTestModel": "gpt-4o"
      }
    }
  }'

Disabling a Channel API Key

To revoke a specific key without deleting the channel, use the disableChannelAPIKey mutation implemented in the resolvers.

curl -X POST http://localhost:8090/openapi/v1/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "query": "mutation($channelID: ID!, $key: String!){disableChannelAPIKey(channelID: $channelID, key: $key)}",
    "variables": {
      "channelID": "1",
      "key": "sk-xxxx"
    }
  }'

Managing Users and Projects

Similar patterns apply to user and project management. The createUser, updateProject, and related mutations follow the same resolver → service → database flow. Refer to internal/server/biz/user.go and internal/server/biz/project.go for the underlying business logic.

Type-Safe Go Client with GenQLient

For production Go applications, use genqlient to generate a type-safe client from the schema.

First, install the tool and generate the client:

go install github.com/Khan/genqlient@latest
genqlient generate ./internal/server/gql/...

Then use the generated code:

package main

import (
	"context"
	"log"
	"os"

	"github.com/Khan/genqlient/graphql"
	"your/module/internal/server/gql/genqlient"
)

func main() {
	token := os.Getenv("AXONHUB_TOKEN")
	httpClient := graphql.NewHTTPClient(
		"http://localhost:8090/openapi/v1/graphql",
		graphql.WithHeader("Authorization", "Bearer "+token),
	)

	ctx := context.Background()
	resp, err := genqlient.CreateChannel(ctx, httpClient, genqlient.CreateChannelInput{
		Type:             genqlient.ChannelTypeOpenAI,
		Name:             "go-client-channel",
		Tags:             []string{"automated"},
		BaseURL:          "https://api.openai.com/v1",
		APIKeys:          []string{"sk-xxxx"},
		SupportedModels:  []string{"gpt-4o-mini"},
		DefaultTestModel: "gpt-4o-mini",
	})
	if err != nil {
		log.Fatalf("createChannel failed: %v", err)
	}
	log.Printf("Created channel ID: %s", resp.ID)
}

Key Source Files

Purpose File
GraphQL schema (all management mutations/queries) internal/server/gql/axonhub.graphql
Resolver implementations (wire GraphQL to services) [internal/server/gql/axonhub.resolvers.go](https://github.com/looplj/axonhub/blob/unstable/internal/server/gql/axonhub.resolvers.go)
Channel business logic [internal/server/biz/channel.go](https://github.com/looplj/axonhub/blob/unstable/internal/server/biz/channel.go)
API‑key business logic [internal/server/biz/apikey.go](https://github.com/looplj/axonhub/blob/unstable/internal/server/biz/apikey.go)
User/role/project services (similar pattern) internal/server/biz/user.go, internal/server/biz/role.go, internal/server/biz/project.go
Authentication endpoint (sign‑in) [internal/server/api/auth.go](https://github.com/looplj/axonhub/blob/unstable/internal/server/api/auth.go)
Gin route registration (auth + GraphQL) [internal/server/routes.go](https://github.com/looplj/axonhub/blob/unstable/internal/server/routes.go)
Server startup & GraphQL handler registration [internal/server/server.go](https://github.com/looplj/axonhub/blob/unstable/internal/server/server.go)
Generated Go client (GenQLient) – after running genqlient generate internal/server/gql/genqlient/... (auto‑generated)

Summary

  • AxonHub exposes a single GraphQL API endpoint at /openapi/v1/graphql for all management operations.
  • The schema is defined in axonhub.graphql and implemented by resolvers in axonhub.resolvers.go, which delegate to business services in internal/server/biz/.
  • Authentication requires a JWT obtained from POST /auth/signin and passed as a Bearer token.
  • You can interact with the API using raw cURL commands or generate a type-safe Go client using genqlient.
  • Key operations include creating channels, disabling API keys, managing users, and configuring projects.

Frequently Asked Questions

What is the AxonHub GraphQL endpoint URL for management operations?

The management GraphQL API is available at /openapi/v1/graphql relative to your AxonHub base URL (e.g., http://localhost:8090/openapi/v1/graphql). This single endpoint handles all administrative queries and mutations, including channel provisioning, user management, and API key rotation, as defined in the schema file internal/server/gql/axonhub.graphql.

How do I authenticate requests to the GraphQL API?

All management calls require a valid JWT token. First, authenticate via the REST endpoint POST /auth/signin (implemented in [internal/server/api/auth.go](https://github.com/looplj/axonhub/blob/unstable/internal/server/api/auth.go)) with your email and password. The response returns a token string that you must include in the Authorization: Bearer <token> header on every GraphQL request. The Gin router enforces this protection in [internal/server/routes.go](https://github.com/looplj/axonhub/blob/unstable/internal/server/routes.go).

Can I use a type-safe client instead of raw HTTP requests?

Yes. AxonHub's GraphQL schema is compatible with genqlient, a Go code generator for GraphQL. By running genqlient generate against internal/server/gql/axonhub.graphql, you produce a type-safe client that validates queries at compile time. This eliminates manual JSON construction and reduces runtime errors when calling management operations like createChannel or disableChannelAPIKey.

Where are the GraphQL resolvers for management operations implemented?

The resolver functions that bridge the GraphQL API to the business layer are located in [internal/server/gql/axonhub.resolvers.go](https://github.com/looplj/axonhub/blob/unstable/internal/server/gql/axonhub.resolvers.go). Each mutation (such as createChannel, disableChannelAPIKey, or createUser) has a corresponding resolver method that validates inputs, invokes the appropriate service in internal/server/biz/, and returns the result to the GraphQL layer.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →