Skip to content
Social SDK Cloud, the hosted SDK, is taking early-access signups.Join the list
Social SDK megaphone markSocial SDK
Esc
↑↓navigate↵open⌘Jpreview
On this page

Native access

Reach platform-specific operations through typed native modules while your application keeps tenant authorization and reconciliation explicit.

The shared operation model covers what every platform can express faithfully. Everything else lives behind typed native access, which is deliberately explicit about what it skips.

Two native surfaces

Adapters expose a typed native module for platform-specific operations: reposts, quotes, polls, follows, profile updates, feed discovery, thumbnails, captions, and more. Platform search routes that have no faithful shared contract remain native; the normalized search.posts operation is listed separately in the capability manifest. The capability matrix lists each platform’s native declarations.

Each platform has its own native module type, and an adapter’s native is optional, so check it before calling. This example uses the Threads adapter, whose native getProfile takes the acting account and an operation context:

import { createSocial, type AdapterOperationContext } from "@opencoredev/social-sdk";
import { threads } from "@opencoredev/social-sdk/threads";

const social = createSocial({ backend: threads({ auth: { userId, accessToken } }) });
const native = social.native("default", { acknowledgeUnsafe: true });
if (native === undefined) throw new Error("This adapter has no native module");

const context: AdapterOperationContext = {
  backendInstance: "default",
  correlationId: crypto.randomUUID(),
  retryBudget: { maxAttempts: 1, maxElapsedMs: 30_000 },
};

// Authorize the account for the current tenant first: native calls skip the policy.
const profile = await native.getProfile({ account, context });

Method names and inputs differ by platform. The X native module, for example, has no getProfile; it uses getMe, getUserById, and getUserByUsername. Check the platform page before calling.

Selected reactions also ship as credential-ready helpers importable straight from a platform entrypoint, such as xLike and xUnlike, for server code that manages its own credentials. Native modules also cover media workflows, graph operations, notification reads, platform search, captions, playlists, analytics products, and gated live or messaging routes where the provider exposes them. Moderation and reporting are not normalized. Some adapters expose them natively: hideReply on X, Threads, and Bluesky, comment moderation on YouTube and Instagram, and createModerationReport on Bluesky. See comments and messages.

Raw provider requests

When a provider ships an endpoint no typed method covers, call request(input, context) on the adapter’s native module; for Zernio it is zernioNative(options).request. It sends one request to a path below one of the adapter’s named hosts, such as Facebook’s graph, video and rupload. The adapter adds its own credentials, checks the account, maps errors, and applies the elapsed budget and cancellation. The result has the status, selected headers and a JSON, text or bytes body.

The adapter refuses absolute URLs, .. segments, credential headers and redirects. Raw requests make one attempt with no idempotency key and no outcome record, so reconcile any write you send; an uncertain write rejects with ambiguous_outcome. A rate-limited response reports the provider’s wait from Retry-After or X’s x-rate-limit-reset. Managed backends report each raw request to their onRequest hook. Each provider page has a “Raw requests” section with its hosts and an example.

const response = await native.request(
  { account, method: "GET", path: "/me", query: { fields: "id,username" } },
  context,
);

What acknowledgeUnsafe means

Native calls bypass the client’s normalized middleware: tenant authorization checks and per-backend concurrency limits do not apply. The acknowledgeUnsafe flag is the contract that your application takes over those responsibilities. Authorize the acting account against the current tenant before every native call, exactly as the client would have.

Native references are preserved

Native operations return provider-native identifiers, like Bluesky’s AT URI and CID or LinkedIn URNs, and the normalized model preserves them in platform post references. Persist what you need for later calls; a like record’s own URI, for example, is what unlike requires.

The same outcome rules apply

Native mutations use bounded transport and do not retry a lost response. Reconcile uncertain acceptance before submitting again, and treat provider-controlled processing or moderation states as pending rather than complete. Fixture coverage of a native operation is not evidence of live authorization or publication.

When to use which surface

Use the normalized operations when the shared model expresses your intent: they carry authorization, concurrency, idempotency, and outcome handling for you. Reach for native access when a platform feature has no faithful shared representation, and wrap it in the same application policy you would want the client to enforce.

Last updated on November 5, 2026