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.tokens is the legacy all-routes path kept for compatibility;
  • Scopes required per endpoint: profiles user:profile_write, friendships friendship:write, call recordings call:recording_write (* or user:* 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.