Go SDK
A small client you can copy into your backend. This is a documented implementation, not a separately published package. It sends the same API envelope for every service through one call method.
Go 1.18+; standard library only. Put the client in a singlebase subdirectory of your Go module. Replace example.com/app in the example with your module path.
Response contract
| Field | Meaning |
|---|---|
data | Operation result; absent on API errors |
error | API error object, or null/nil on success; message is the stable code |
meta | Response metadata, including pagination when returned |
exec_time | Gateway execution time in seconds, when returned |
API errors return in Result.error. Network, invalid JSON, and transport failures raise an exception or return a Go error. These small clients do not manage sessions, auto-refresh tokens, or retry requests. Pass a current user bearer token to the constructor/client only when acting as that user; omit it for trusted server/agent calls. Keep keys on the server.
Client implementation
Save as singlebase.go. Download the source.
go
package singlebase
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"time"
)
type Result struct {
Data json.RawMessage `json:"data"`
Error map[string]any `json:"error"`
Meta map[string]any `json:"meta"`
ExecTime *float64 `json:"exec_time"`
}
type Client struct {
APIURL string
APIKey string
Bearer string
}
func (s Client) Call(ctx context.Context, operation string, payload map[string]any, options map[string]any) (Result, error) {
body := map[string]any{"operation": operation, "payload": payload}
if options != nil {
body["options"] = options
}
raw, err := json.Marshal(body)
if err != nil {
return Result{}, err
}
req, err := http.NewRequestWithContext(ctx, "POST", s.APIURL, bytes.NewReader(raw))
if err != nil {
return Result{}, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-KEY", s.APIKey)
if s.Bearer != "" {
req.Header.Set("Authorization", "Bearer "+s.Bearer)
}
httpClient := &http.Client{Timeout: 30 * time.Second}
res, err := httpClient.Do(req)
if err != nil {
return Result{}, err
}
defer res.Body.Close()
var result Result
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
return Result{}, err
}
if res.StatusCode >= 400 && result.Error == nil {
return result, fmt.Errorf("HTTP %d without an API error envelope", res.StatusCode)
}
return result, nil
}Example
Set SINGLEBASE_API_URL to the complete console endpoint and SINGLEBASE_API_KEY to your server or appropriately scoped agent key. The notes collection must exist.
go
package main
import (
"context"
"fmt"
"os"
"example.com/app/singlebase"
)
func main() {
sbc := singlebase.Client{APIURL: os.Getenv("SINGLEBASE_API_URL"), APIKey: os.Getenv("SINGLEBASE_API_KEY")}
resp, err := sbc.Call(context.Background(), "data.query", map[string]any{"collection": "notes", "limit": 5}, map[string]any{})
if err != nil { panic(err) }
if resp.Error != nil { panic(resp.Error["message"]) }
fmt.Println(string(resp.Data), resp.Meta, resp.ExecTime)
}Use the same method with llm.summarize for generation or chat.ask for an answer, with the operation's verified payload. The options argument goes in the request envelope, separate from payload. An empty options object is valid; omit it when unused. See API overview for request access and errors, and API reference for the operation groups.