Node.js SDK
@postra/node is a small Node.js library for the Public API. It lists your channels, uploads media, and creates, lists and deletes posts.
| Package | @postra/node |
| Current version | 1.1.1 |
| Node.js | 18 or newer |
| Dependencies | None |
Install
npm install @postra/node
Create a client
You need an API key. Copy it from Settings → Developers → Access in Postra. See Developer settings.
Keep the key on your server, for example in an environment variable. Never put it in a web page or a mobile app.
ES modules and TypeScript:
import Postra from '@postra/node';
const postra = new Postra(process.env.POSTRA_API_KEY); // YOUR_API_KEY
CommonJS (require):
const Postra = require('@postra/node').default;
const postra = new Postra(process.env.POSTRA_API_KEY);
The client sends the key in the Authorization header. An OAuth access token (it starts with pos_) works in the same place. See Sign in with Postra.
The second argument is the API address. It defaults to https://app.postra.co.uk/api, so you can leave it out.
Methods
Every method returns a promise with the API’s JSON answer.
| Method | What it does |
|---|---|
integrations() |
Lists your connected channels |
post(body) |
Creates a draft, a scheduled post or a post that goes out now |
postList(filters) |
Lists posts between two dates |
upload(file, extension) |
Uploads an image or video to your media library |
mediaList(filters) |
Lists your media library |
deletePost(id) |
Deletes a post |
integrations()
const channels = await postra.integrations();
// [{ id, name, identifier, picture, disabled, profile, customer }, ...]
Use a channel’s id when you create a post.
post(body)
const result = await postra.post({
type: 'schedule', // 'draft', 'schedule' or 'now'
date: '2026-11-02T09:30:00.000Z',
shortLink: false,
tags: [],
posts: [
{
integration: { id: 'CHANNEL_ID' },
value: [{ content: 'Hello from Postra', image: [] }],
},
],
});
// [{ postId, integration }]
Some platforms need extra settings in posts[].settings. See Platforms and settings and Endpoints for every field.
postList(filters)
const { posts } = await postra.postList({
startDate: '2026-11-01T00:00:00.000Z',
endDate: '2026-11-30T23:59:59.000Z',
});
Dates are ISO 8601. A range longer than 370 days is cut to 370 days. customer is optional: a customer ID, to list only that customer’s channels.
upload(file, extension)
import { readFile } from 'node:fs/promises';
const media = await postra.upload(await readFile('photo.jpg'), 'jpg');
// use media.id and media.path in a post's image list
file is a Buffer. extension is the file type, such as png, jpg, gif, webp or mp4. File types and sizes are on Uploading media.
To add the file to a post:
value: [{ content: 'New in store', image: [{ id: media.id, path: media.path }] }]
mediaList(filters)
const { pages, results } = await postra.mediaList({ page: 1, search: 'logo' });
// results: [{ id, name, originalName, path, createdAt }, ...]
Newest first, 18 items per page. Both filters are optional. search matches the original file name. Reuse an id and path instead of uploading the same file again.
deletePost(id)
await postra.deletePost('POST_ID');
id is a postId from post() or an id from postList(). This deletes the post on that channel and its follow-up parts, such as thread replies.
Errors
When the API answers with anything other than 2xx, the method throws a PostraError.
| Property | Meaning |
|---|---|
status |
The HTTP status, for example 401 |
body |
The API’s answer, parsed from JSON when possible |
message |
For example Postra API responded 401: {"msg":"Invalid API key"} |
import { PostraError } from '@postra/node';
try {
await postra.integrations();
} catch (err) {
if (err instanceof PostraError) {
console.log(err.status, err.body);
} else {
throw err; // for example, no network
}
}
With require, use const { PostraError } = require('@postra/node');.
A network failure is not a PostraError. It comes through as the normal fetch error.
Common answers:
| Status | Body | Meaning |
|---|---|---|
401 |
{"msg":"Invalid API key"} |
Wrong key, or the key was rotated |
401 |
{"msg":"Invalid OAuth token"} |
The pos_ token is unknown or no longer valid |
401 |
{"msg":"No subscription found"} |
The workspace has no active plan |
429 |
Too many requests. Wait and try again. |
More on the Endpoints page.