Quickstart
zhyper publishes to social platforms through one API. This page gets you from an empty account to a profile you can attach social accounts to.
Everything below runs in test mode, so nothing reaches a real platform. See Test mode for what that means exactly.
1. Get a key
Sign up at the panel, open Settings → API keys, and create one. You will see the key value once — store it immediately; only its prefix and last four characters are shown afterwards.
Test keys start with sk_test_, live keys with sk_.
2. Get a client
There is no published npm package. @zhyper/sdk is deliberately unpublished
— the decision was taken on 2026-08-05 and has not changed — and the name is not
taken on any registry, so npm install @zhyper/sdk does not resolve. Do not
plan around it appearing.
What you build against instead is the OpenAPI document, which is the actual contract. It is public, it is the same document this API is served from, and it is what every generator needs:
# Fetch it from the API itself...
curl -s https://api.zhyper.dev/v1/openapi.json -o openapi.json
# ...or from the marketing site, which serves the same document
curl -s https://zhyper.dev/openapi.json -o openapi.json
# Then point whatever OpenAPI generator you already use at the file.
# With no preference, this one emits types for every request and response:
npx openapi-typescript openapi.json -o zhyper-api.d.ts
If your generator wants a base URL and the copy you fetched does not carry a
servers entry, use the API origin itself — https://api.zhyper.dev/v1.
The TypeScript samples on these pages import from @zhyper/sdk, because they
are compiled and executed against a real test-mode API from inside this
project's own workspace. Read them as the request shape — the operation
name, the body, the query, the order of calls. Every one of those maps directly
onto whatever client you generate, because both are produced from the same
document. Where a sample calls zhyper.request('createProfile', ...), your
client will have a createProfile operation with exactly that body.
Node.js 22 or newer for the samples as written.
3. Create a profile
A profile is a brand or client — the container that social accounts, queues and posts belong to. Every account you connect lives under one.
export async function createFirstProfile(
zhyper: ZhyperClient,
): Promise<Schemas['ProfileDto']> {
const profile = await zhyper.request<Schemas['ProfileDto']>('createProfile', {
body: {
name: 'Acme Corp',
timezone: 'Europe/Istanbul',
},
});
return profile;
}
The response gives you the profile id you will use everywhere else:
{
"id": "a1b2c3d4e5f6a7b8c9d0e1f2",
"name": "Acme Corp",
"timezone": "Europe/Istanbul"
}
timezone must be an IANA zone. It decides when "9am" means 9am — queue slots
and scheduled posts are resolved against it.
4. List what you have
Lists are cursor-paginated. The SDK follows the cursor for you:
export async function listAllProfiles(zhyper: ZhyperClient): Promise<string[]> {
const names: string[] = [];
// paginate cursor'u sizin icin izler ve satirlari tek tek verir.
for await (const profile of zhyper.paginate<Schemas['ProfileDto']>('listProfiles', {
query: { limit: 50 },
})) {
names.push(profile.name);
}
return names;
}
If you page manually, read hasMore and nextCursor from the envelope and pass
nextCursor back as the cursor query parameter. Stop when hasMore is false
or nextCursor is null.
5. Read one back
export async function readProfile(
zhyper: ZhyperClient,
id: string,
): Promise<Schemas['ProfileDto']> {
// Yol parametresinin adi `profileId`, `id` DEGIL. Bu ornek `id` gonderiyordu
// ve SDK istemcisi sunucuya HIC ULASMADAN TypeError firlatiyordu -- yani
// MUSTERIYE YAYINLANMIS, kopyalandiginda calismayan bir ornekti. Olculdu:
// `apps/api/openapi.json` -> `/v1/profiles/{profileId}` GET, tek parametre
// `profileId`. `apps/api/test/docs-examples.test.ts` tam da bunu yakalamak
// icin var (ornegi GERCEK API'ye karsi kosar) ve iki testi bu yuzden
// kirmiziydi; kirmizi ornegin kendisini isaret ediyordu, testi degil.
return zhyper.request<Schemas['ProfileDto']>('getProfile', {
path: { profileId: id },
});
}
A profile your key cannot reach returns 404, exactly like one that does not
exist. That is deliberate: a scoped key cannot use error codes to discover which
ids exist.
Next
- Authentication — keys versus panel sessions
- Test mode — how the sandbox actually works
- Webhooks — receiving events
- Errors — the error envelope
- Rate limits and idempotency