SDK · Server Side

Five server SDKs with zero third-party dependencies, sharing one behavior matrix and the /openapi/v1 wire contract:

Language Package Minimum runtime Tests
Go github.com/obihuang/imcore/clients/go (imcoreadmin) Go 1.22 go test
Node @imcore/admin (TS, native type-stripping, no build step) Node ≥ 22.6 node --test
Python imcore-admin (stdlib) Python ≥ 3.9 unittest
Java imcore-admin-java (JDK 17, java.net.http + hand-written flat JSON) Java 17+ JUnit 5 (stub on the JDK built-in HttpServer)
PHP imcore/admin (8.1+, ext-curl + native JSON) PHP ≥ 8.1 Built-in php -S stub (verified with docker php:8.1-cli)

Behavior is fully aligned (the five test matrices lock one another down): Bearer auth, automatic batching against the server-side 100-item limit with an accumulated processed, local pre-validation (empty userID, userA == userB, missing call_id/recording_url fail before any request is sent), typed errors for non-2xx (with index/processed batch details and 401/403/404/400/5xx predicates, where 404 also means the server feature is not enabled), and no automatic retries (batches are idempotent, so retrying after 5xx is safe).

Prerequisites (Server Configuration, Common to All Three Languages)

  • openapi.enabled = true (off by default; all endpoints return 404 when disabled);
  • Bearer token: scoped service credentials (admin console /admin/api/openapi/credentials) or the legacy openapi.tokens;
  • Scopes: profiles user:profile_write, friendships friendship:write, recordings call:recording_write (* / user:* wildcards work);
  • The recording endpoint requires the AI SKU and call_analysis.enabled = true, otherwise 404.

Node (@imcore/admin)

tar xzf imcore-sdk-node-<version>.tar.gz
# package.json dependency: "@imcore/admin": "file:./imcore-sdk-node-<version>"
import { ImcoreAdminClient } from '@imcore/admin';

const client = new ImcoreAdminClient('https://im.example.com', '<token>');
const processed = await client.upsertProfiles([{ userID: '1001', userName: 'alice' }]);
await client.upsertFriendships([{ userA: '1001', userB: '2002' }]);
const result = await client.ingestCallRecording({
  call_id: 'call-9', recording_url: 'https://records/9.mp3',
  direction: 'inbound', started_at: 1760000000, duration_sec: 183,
});

// Error handling
import { asAdminError } from '@imcore/admin';
try {
  await client.removeFriendships([{ userA: '1001', userB: '2002' }]);
} catch (error) {
  const adminError = asAdminError(error);
  if (adminError?.isForbidden()) {
    // the credential is missing the friendship:write scope
  }
}

Timeout defaults to 10s; inject a custom HTTP transport via the transport option (for tests/proxies).

Python (imcore-admin)

tar xzf imcore-sdk-python-<version>.tar.gz
pip install ./imcore-sdk-python-<version>
from imcore_admin import ImcoreAdminClient, ProfileItem, FriendshipItem, CallRecording

client = ImcoreAdminClient("https://im.example.com", "<token>")
client.upsert_profiles([ProfileItem(userID="1001", userName="alice")])
client.upsert_friendships([FriendshipItem(userA="1001", userB="2002")])
result = client.ingest_call_recording(CallRecording(
    call_id="call-9", recording_url="https://records/9.mp3",
    direction="inbound", started_at=1760000000, duration_sec=183))

For the Go version, see SDK_GO.md.

Scope and What’s Next

All five languages cover the four inbound endpoints of /openapi/v1. Java usage (AdminClient.create(...); build: cd clients/kotlin && ./gradlew -p ../java test); PHP usage (AdminClient::create(...), items are arrays carrying the wire keys; tests: docker run --rm -v "$PWD/clients/php":/work -w /work php:8.1-cli php tests/run.php). Next up: retry/rate-limit wrappers and public repository publishing (Go proxy / npm / PyPI / Maven Central / Packagist) — see the SDK platform compatibility matrix.