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 legacyopenapi.tokens; - Scopes: profiles
user:profile_write, friendshipsfriendship:write, recordingscall: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.