> ## Documentation Index
> Fetch the complete documentation index at: https://docs.postsider.com/llms.txt
> Use this file to discover all available pages before exploring further.

# @postsider/node SDK Complete Method Reference Guide

> Full reference for all @postsider/node SDK methods: post, postList, upload, integrations, deletePost, verifyWebhookSignature, and more.

This page is the complete reference for every method exposed by the `@postsider/node` SDK. Each entry documents the method signature, its parameters, the value it returns, and a usage example. For installation and setup instructions, see the [SDK Overview](/sdk/overview).

***

## `new Postsider(apiKey, instanceUrl?)`

Creates a new SDK client. Instantiate this once and reuse it across your application.

```typescript theme={null}
import Postsider from '@postsider/node';

const client = new Postsider('your-api-key', 'https://your-instance.com');
```

<ParamField body="apiKey" type="string" required>
  Your organization's API key. Generate one from **Settings → API Keys** in the Volta dashboard.
</ParamField>

<ParamField body="instanceUrl" type="string">
  The base URL of your Volta instance (e.g. `"https://your-instance.com"`). Defaults to `"https://api.postsider.com"` for the Volta hosted service.
</ParamField>

***

## `client.post(posts)`

Schedules a post or saves it as a draft. Maps to `POST /public/v1/posts`.

```typescript theme={null}
await client.post({
  type: 'schedule',
  date: '2025-01-15T10:00:00',
  posts: [
    {
      integration: { id: 'ch_abc123' },
      value: [
        {
          content: 'Hello from Volta!',
          image: ['media_xyz789'] // optional
        }
      ]
    }
  ]
});
```

<ParamField body="posts" type="CreatePostDto" required>
  The post configuration object.

  <ParamField body="type" type="string" required>
    `"schedule"` to publish at the specified time, or `"draft"` to save without scheduling.
  </ParamField>

  <ParamField body="date" type="string">
    ISO 8601 publish time (e.g. `"2025-01-15T10:00:00"`). Required when `type` is `"schedule"`.
  </ParamField>

  <ParamField body="posts" type="array" required>
    Array of per-channel content objects. Each entry targets one connected channel.

    <ParamField body="posts[].integration.id" type="string" required>
      The ID of the target channel. Retrieve IDs from `client.integrations()`.
    </ParamField>

    <ParamField body="posts[].value" type="array" required>
      Array of content blocks for this channel.

      <ParamField body="posts[].value[].content" type="string">
        The text body of the post.
      </ParamField>

      <ParamField body="posts[].value[].image" type="array">
        Optional array of media IDs from `client.upload()`.
      </ParamField>
    </ParamField>
  </ParamField>
</ParamField>

**Returns:** `Promise<{ id: string; status: string }>` — the new post's ID and its initial status.

***

## `client.postList(filters)`

Retrieves a paginated list of posts for your organization. Maps to `GET /public/v1/posts`.

```typescript theme={null}
const posts = await client.postList({ page: 0, limit: 20 });
console.log(posts);
```

<ParamField body="filters" type="GetPostsDto" required>
  Pagination and filter options.

  <ParamField body="page" type="number">
    Zero-indexed page number. Defaults to `0`.
  </ParamField>

  <ParamField body="limit" type="number">
    Number of results per page. Defaults to `20`.
  </ParamField>
</ParamField>

**Returns:** `Promise<Post[]>` — an array of post objects matching the filters.

***

## `client.upload(file, extension)`

Uploads a media file to the Volta media library. Maps to `POST /public/v1/upload`. The SDK handles multipart form encoding and MIME type mapping for you.

```typescript theme={null}
import { readFileSync } from 'fs';

const buffer = readFileSync('./photo.jpg');
const media = await client.upload(buffer, 'jpg');

console.log(media.id);  // use in client.post()
console.log(media.url); // publicly accessible URL
```

<ParamField body="file" type="Buffer" required>
  A Node.js `Buffer` containing the raw file bytes.
</ParamField>

<ParamField body="extension" type="string" required>
  The file extension that determines the MIME type. Accepted values: `'png'`, `'jpg'`, `'jpeg'`, `'gif'`, `'mp4'`.
</ParamField>

**Returns:** `Promise<{ id: string; url: string }>` — the uploaded file's ID and public URL.

***

## `client.integrations()`

Returns all channels currently connected to your organization. Maps to `GET /public/v1/integrations`.

```typescript theme={null}
const channels = await client.integrations();

for (const channel of channels) {
  console.log(channel.id, channel.name, channel.providerIdentifier);
}
```

**Returns:** `Promise<Channel[]>` — an array of channel objects, each with `id`, `name`, `providerIdentifier`, `profile`, and `picture`.

***

## `client.listConnectors()`

Returns all connector types available on your Volta instance, including their authorization status and supported capabilities. Maps to `GET /public/v1/connectors`. Useful in agent workflows to discover which platforms are ready before attempting to authorize or post.

```typescript theme={null}
const connectors = await client.listConnectors();

const ready = connectors.filter(c => c.authorized);
console.log('Ready to post:', ready.map(c => c.name));
```

**Returns:** `Promise<Connector[]>` — an array of connector descriptors with `id`, `name`, `authorized`, and `capabilities`.

***

## `client.authorizeConnector(connectorId)`

Starts the OAuth authorization flow for a connector. Maps to `POST /public/v1/connectors/:id/authorize`. Returns an OAuth redirect URL if authorization is required, or confirms immediately if the connector is already authorized.

```typescript theme={null}
const result = await client.authorizeConnector('linkedin');

if ('url' in result) {
  // Redirect the user to result.url to complete OAuth
  console.log('Authorize at:', result.url);
} else {
  console.log('Already authorized');
}
```

<ParamField body="connectorId" type="string" required>
  The connector identifier (e.g. `"x"`, `"linkedin"`, `"instagram"`). Retrieve valid IDs from `client.listConnectors()`.
</ParamField>

**Returns:** `Promise<{ url: string } | { authorized: true }>` — either an OAuth URL to redirect to, or a confirmation that the connector is already authorized.

***

## `client.connectorAnalytics(connectorId, date)`

Fetches analytics for a connected channel on a given date. Maps to `GET /public/v1/connectors/:id/analytics`. The response shape is platform-specific.

```typescript theme={null}
const stats = await client.connectorAnalytics('ch_abc123', '2025-01-15');
console.log(stats);
```

<ParamField body="connectorId" type="string" required>
  The ID of the connected channel. Use the `id` field from `client.integrations()`.
</ParamField>

<ParamField body="date" type="string" required>
  The date for which to retrieve analytics, formatted as `YYYY-MM-DD` (e.g. `"2025-01-15"`).
</ParamField>

**Returns:** `Promise<Record<string, unknown>>` — a platform-specific analytics object. Common fields include `impressions`, `likes`, `reposts`, and `followers`.

***

## `client.deletePost(id)`

Deletes a post by its ID. Maps to `DELETE /public/v1/posts/:id`.

```typescript theme={null}
await client.deletePost('post_abc123');
```

<ParamField body="id" type="string" required>
  The unique identifier of the post to delete. Use the `id` returned when creating the post or from `client.postList()`.
</ParamField>

**Returns:** `Promise<Response>` — the raw `node-fetch` Response object. A `200` status indicates success.

***

## `Postsider.verifyWebhookSignature(signature, body, secret)` <span style={{ fontSize: '0.75em', color: 'gray' }}>static</span>

Verifies the HMAC-SHA256 signature on an inbound Volta webhook request. Call this at the top of your webhook handler before processing any event data. The method uses a timing-safe comparison to prevent timing attacks.

The `X-Postsider-Signature` header value is formatted as `sha256=<hex-digest>`.

```typescript theme={null}
import Postsider from '@postsider/node';

app.post('/webhook', (req, res) => {
  const isValid = Postsider.verifyWebhookSignature(
    req.headers['x-postsider-signature'] as string,
    JSON.stringify(req.body),
    process.env.WEBHOOK_SECRET!
  );

  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }

  // Safe to process the event
  const event = req.body;
  console.log('Received event:', event);

  res.status(200).send('OK');
});
```

<ParamField body="signature" type="string" required>
  The value of the `X-Postsider-Signature` header from the incoming request (e.g. `"sha256=abc123..."`).
</ParamField>

<ParamField body="body" type="string" required>
  The raw request body as a string. If your framework parses JSON automatically, serialize it back with `JSON.stringify(req.body)` to ensure the string matches what was signed.
</ParamField>

<ParamField body="secret" type="string" required>
  Your webhook signing secret. Configure this in the Volta dashboard when setting up the webhook subscription.
</ParamField>

**Returns:** `boolean` — `true` if the signature is valid, `false` otherwise. Always reject requests that return `false`.

<Warning>
  Always pass the **raw** request body string to this method. If you pass a re-serialized or pretty-printed version of the parsed JSON, the HMAC will not match even for legitimate requests.
</Warning>
