SDK · Go
github.com/obihuang/imcore/clients/go (package name imcoreadmin) is a zero-dependency Go client
for imcore’s inbound server API (/openapi/v1): push user profiles and friendships from your own
business backend, and report call recordings. It uses only the standard library (net/http +
encoding/json), is a standalone Go module (go 1.22), and introduces no server-side dependencies.
Prerequisites (Server Configuration)
openapi.enabled = true— master switch for the inbound group (off by default; all endpoints return 404 when disabled);- Auth: Bearer token. Prefer scoped service credentials (created in the admin console at
/admin/api/openapi/credentials; the token is shown only once);openapi.tokensis the legacy all-routes path kept for compatibility; - Scopes required per endpoint: profiles
user:profile_write, friendshipsfriendship:write, call recordingscall:recording_write(*oruser:*prefix wildcards work); - The call recording endpoint additionally requires the AI SKU and
call_analysis.enabled = true, otherwise 404.
Installation
# Source package from the download page (recommended, versioned tarball)
tar xzf imcore-sdk-go-<version>.tar.gz # yields imcore-sdk-go/
go mod edit -replace github.com/obihuang/imcore/clients/go=./imcore-sdk-go
go get github.com/obihuang/imcore/clients/go
Usage
package main
import (
"context"
"fmt"
"log"
admin "github.com/obihuang/imcore/clients/go"
)
func main() {
client, err := admin.NewClient("https://im.example.com", "<service-credential-token>")
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// After user registration / profile changes: push profile projections
// (empty userName/avatar keeps the server-side stored value)
processed, err := client.UpsertProfiles(ctx, []admin.ProfileItem{
{UserID: "1001", UserName: "alice", Avatar: "https://cdn/a.png"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println("profiles processed:", processed)
// After friendships are created/removed on the business side: two-way sync
if _, err := client.UpsertFriendships(ctx, []admin.FriendshipItem{
{UserA: "1001", UserB: "2002"},
}); err != nil {
log.Fatal(err)
}
// After a contact-center call ends: report the recording
// (idempotent on call_id; duplicate reports return deduped=true)
result, err := client.IngestCallRecording(ctx, admin.CallRecording{
CallID: "call-2026-0009",
RecordingURL: "https://records.example.com/call-0009.mp3",
Direction: "inbound",
FromNumber: "+10000000001",
ToNumber: "+10000000002",
AgentID: "agent-7",
StartedAt: 1760000000,
DurationSec: 183,
})
if err != nil {
var adminErr *admin.Error
if admin.AsAdminError(err) && adminErr.IsNotFound() {
log.Fatal("endpoint not enabled: check call_analysis.enabled and the AI SKU")
}
log.Fatal(err)
}
fmt.Printf("ingested %s status=%s deduped=%v\n", result.CallID, result.Status, result.Deduped)
}
Behavioral Details
| Semantics | Description |
|---|---|
| Batching | 100 items max per request (server constraint); the SDK auto-batches larger slices and accumulates processed; a failure between batches short-circuits and returns the number already processed |
| Local pre-validation | Empty userID, userA == userB, missing call_id/recording_url, etc. fail client-side with *admin.Error (400 semantics) without sending a request |
| Error mapping | Non-2xx returns *admin.Error{StatusCode, Code, Index, Processed}; IsUnauthorized/IsForbidden/IsNotFound/IsValidation/IsServerError cover the server status classes, and 404 also means “server feature not enabled” |
| Retries | The SDK does not retry automatically; inbound batches are idempotent, so retrying with the same data after 5xx/timeout is safe |
| Timeout | 10s by default; customize with admin.WithHTTPClient(...) |
| Concurrency | Client is safe for concurrent reuse (a single http.Client) |
Tests and Versioning
cd clients/go && go test ./...
The version constant admin.SDKVersion is kept in sync with clients/SDK_VERSION
(guarded in CI by scripts/check_sdk_version.sh). The full HTTP contract is also
available as OpenAPI 3.1 documentation, served directly by a deployed instance at
/openapi.yaml / /openapi.json.
Scope and What’s Next
The initial release covers all four inbound endpoints of /openapi/v1. The Node (@imcore/admin)
and Python (imcore-admin) versions share the same behavior matrix — see
SDK_SERVER.md. Next up: Java/PHP languages, automatic
retry/rate-limit wrappers, and public repository publishing — see the
SDK platform compatibility matrix.