SDK and CLI
Two packages on npm: @praeko/sdk, to call the API from your code, and @praeko/cli, the praeko command in your terminal.
Install
SDK, in your project
npm install @praeko/sdkyarn add @praeko/sdkpnpm add @praeko/sdkbun add @praeko/sdkCLI, in your terminal
npm install -g @praeko/cliyarn global add @praeko/clipnpm add -g @praeko/clibun add -g @praeko/clinpx @praeko/cli --help
pnpm dlx @praeko/cli --help
bunx @praeko/cli --help
yarn dlx @praeko/cli --help # yarn 2 or newerThe SDK has no dependencies, ships TypeScript types and runs on Node 22 or newer, Cloudflare Workers, Deno, Bun and in the browser. The CLI is published with the SDK bundled in, so there is nothing else to install. The only command is praeko.
SDK quick start
Create an API key in the panel (or with praeko key create) and keep it in PRAEKO_KEY. Never put the key in your source code or in the browser.
import { Praeko } from "@praeko/sdk";
import { uploadFile } from "@praeko/sdk/node"; // Node only: uploads the file from disk in parts
const praeko = new Praeko({ url: "https://praeko.app", key: process.env.PRAEKO_KEY });
const video = await uploadFile(praeko, "./video.mp4", { type: "video", onProgress: (done, total) => {} });
const post = await praeko.posts.create({
title: "My video",
media: { video: video.id },
texts: { youtube: { title: "My video", text: "Video description" } },
items: [{ network: "youtube", queue: true }],
});
console.log(post.id);Outside Node (Workers, browser), pass a Uint8Array, a Blob or { size, read(start, n) } to praeko.media.upload(source, { type, name, mime }). The upload picks a single request or several parts by size on its own. In the browser, on the same origin as the panel, use { cookies: true } instead of the key.
Retries and safe repeats
| Call | Retries by itself on network failure, `429` and `5xx`? |
|---|---|
GET and media part uploads |
Yes, up to 3 attempts (change it with retries). |
POST, PATCH and DELETE |
No, so nothing is duplicated. With the idempotencyKey option, yes: the SDK resends with the same key. |
// true: the SDK generates a UUID and reuses it on every attempt of this call
const post = await praeko.posts.create({ title, media: { video: video.id }, texts, items }, { idempotencyKey: true });
// or choose the key yourself, for example one from your own job
await praeko.webhooks.create({ url: "https://example.com/hooks/praeko", idempotencyKey: `hook-${jobId}` });See the header rules in Retry a request safely. Errors become a PraekoError, with status, code (stable, in English), message and details:
import { PraekoError } from "@praeko/sdk";
try { await praeko.posts.get("nao-existe"); }
catch (e) { if (e instanceof PraekoError && e.code === "not_found") { /* … */ } else throw e; }The routes and the error codes are also typed in @praeko/sdk/contract (ROUTES, ERROR_CODES).
CLI commands
Point the CLI at the service with --server https://praeko.app (or PRAEKO_SERVER) and give the key in PRAEKO_KEY. Nothing is sent, hosted or scheduled without --send: without it, post only simulates. The CLI messages are in English (CLI 0.4.0).
| Command | Does |
|---|---|
praeko post <folder> --queue, --when … or --draft |
Creates a post from a folder with publication.json, the video and the cover (needs a praeko.json in the current folder or above). Simulates unless you pass --send. |
praeko posts |
Lists posts by --state, --channel, --tag, --limit. |
praeko calendar |
Scheduled items and free slots, with --from and --to. |
praeko slots <network> [day time …] |
Shows or replaces the weekly slots. |
praeko publish-now <id> [--idempotency-key K] |
Takes the post out of the queue and publishes now. The key prevents publishing twice if you run the command again. |
praeko channels |
What is connected. |
praeko insights |
Metrics, with --days, --channel, --compare, --json. |
praeko content |
Everything already published. |
praeko youtube videos, edit, comments, reply |
Channel videos, title and description edits, unanswered comments and replies. Edits and replies simulate until --send. |
praeko key create, list, revoke |
API keys (needs an admin key). |
praeko webhook list, create --url … [--idempotency-key K], test, deliveries, retry |
Outgoing webhooks, admin scope. The secret is shown once. |
praeko usage and praeko usage log |
API usage and the request log of the last 30 days. |
praeko help |
The full list, with every option. |
export PRAEKO_KEY="praeko_…"
export PRAEKO_SERVER="https://praeko.app"
praeko --version
praeko channels
praeko post ./my-video --queue # simulates
praeko post ./my-video --queue --send # schedules for realExit codes: 0 success; 1 error (message in English on stderr); 2 invalid command or argument (prints the help). The CLI does not retry on its own: --idempotency-key is for whoever runs the command again, for example in a script with retries.
Key and environment variables
| Variable | What it does |
|---|---|
PRAEKO_KEY |
The API key. |
PRAEKO_SERVER |
The service address, https://praeko.app. Replaces --server. |
PRAEKO_SECRETS |
A different path for the secrets file (the default is ~/.config/praeko/secrets.json, mode 600). |
PRAEKO_NO_KEYCHAIN |
1 ignores the macOS Keychain. |
Without PRAEKO_KEY, the CLI looks for the key in the macOS Keychain (Mac only) and in the secrets file. On Linux and Windows, the variable and the file apply.
Versions
SemVer. While the version is 0.x, a breaking change can ship in a minor version, and each one is listed in the CHANGELOG.md of the package. praeko studio hands over to Praeko Studio (@praeko/studio), installed separately.
arauto command left the package in CLI 0.1.1: use praeko (if you used 0.1.0 you can run npx -p @praeko/cli praeko). Since CLI 0.4.0 (11/08/2026) the CLI accepts only English commands, options and files (publication.json, PRAEKO_SECRETS, PRAEKO_NO_KEYCHAIN; see the changelog); the ARAUTO_CHAVE variable is still read, and Arauto remains an alias in the SDK. The Portuguese names in the SDK (chave, enviarArquivo…) are deprecated aliases and will be removed in a future version.