Quickstart
Build and verify your first Social SDK flow without credentials, platform calls, or billable provider requests.
To test social posting code without real API keys, give createSocial the mockBackend from @opencoredev/social-sdk/testing instead of a platform adapter. Your code makes the same social.posts.publish call it makes in production, with no credentials and no network request, and the scenario you pick decides the result: an immediate published outcome, media that reports processing until your test calls mock.testing.advanceProcessing(), a rate-limited failed outcome, or a mixed batch where every second target fails.
The deterministic testing backend is the safe first integration target. It accepts explicit accounts, fixtures, scenarios, and a fake clock so the same input produces the same observable result in local development and CI.
npm install @opencoredev/social-sdkpnpm add @opencoredev/social-sdkyarn add @opencoredev/social-sdkbun add @opencoredev/social-sdknub add @opencoredev/social-sdkaube add @opencoredev/social-sdkSave this as quickstart.ts:
import { createSocial, connectedAccountRef } from "@opencoredev/social-sdk";
import { MemoryIdempotencyStore, mockBackend } from "@opencoredev/social-sdk/testing";
const mock = mockBackend({ scenario: "immediate-text-success" });
const social = createSocial({
backend: mock,
idempotencyStore: new MemoryIdempotencyStore(),
});
const result = await social.posts.publish({
targets: [
{
account: connectedAccountRef({
backend: "default",
platform: "x",
accountId: "mock-account-1",
}),
},
],
content: { text: "Hello from the deterministic mock." },
idempotencyKey: "docs-quickstart-1",
});
console.log(result.status, result.outcomes[0]?.state);
// complete published
Run it with bun quickstart.ts, or on Node.js with npx tsx quickstart.ts. It runs without credentials and makes no network request. The repository keeps a tested copy in examples/snippets/mock-quickstart.ts.
What the example proves
- The application selects an account reference that belongs to the configured backend instance.
- It creates one publication intent with explicit targets and content.
- The backend returns one independent delivery outcome for each target.
- In the
immediate-text-successscenario that outcome ispublished, so the publication iscomplete. Other scenarios return pending states such asprocessing; the next section shows a mixed result. - No network request, credential lookup, timer, telemetry event, or background poll happens implicitly.
Failure exercise
The mixed-success-failure scenario fails every second target. Publish to both mock accounts:
const mixed = createSocial({
backend: mockBackend({ scenario: "mixed-success-failure" }),
idempotencyStore: new MemoryIdempotencyStore(),
});
const result = await mixed.posts.publish({
targets: [
{
account: connectedAccountRef({
backend: "default",
platform: "x",
accountId: "mock-account-1",
}),
},
{
account: connectedAccountRef({
backend: "default",
platform: "threads",
accountId: "mock-account-2",
}),
},
],
content: { text: "Hello from the deterministic mock." },
idempotencyKey: "docs-quickstart-2",
});
console.log(
result.status,
result.outcomes.map((outcome) => outcome.state),
);
// partial [ "published", "failed" ]
Keep the successful delivery and display the failed target’s code, message, and retryDisposition. Calling publish again with the same key returns these saved outcomes without dispatching. A retry of only the failed target needs a new key; see idempotency for when that is safe.
Next: a real route
Once the flow works against the mock, switch the backend to a real one. Each guide has a complete publish example:
- Direct platforms: X, Bluesky, YouTube, and the rest of the platform guides.
- Managed backends: Zernio, Post for Me, PostFast, Postiz, and Buffer.
The agent integration checklist turns this mock flow into a repeatable implementation and verification sequence.
Cleanup
Mock state is process-local. mock.testing.reset() clears the mock’s call history and processing flag but keeps the scenario and any delivery records it created, and MemoryIdempotencyStore.reset() clears its claims. For full isolation, create a fresh mockBackend and store per test, and reset the fake clock, so outcomes do not depend on test order.