JavaScript Quick Start

View as Markdown

JavaScript syntax for the five Core Workflows. That page owns request ordering, response semantics, and upload behavior.

Setup

const baseUrl = 'https://api.publora.com/api/v1';
const apiKey = process.env.PUBLORA_API_KEY;
 
async function publora(path, { idempotencyKey, ...init } = {}) {
  const response = await fetch(`${baseUrl}/${path}`, {
    ...init,
    headers: {
      'content-type': 'application/json',
      'x-publora-key': apiKey,
      ...(idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : {}),
      ...init.headers,
    },
  });
  const body = await response.json();
  if (!response.ok) throw new Error(body.error ?? `HTTP ${response.status}`);
  return body;
}
 
const platformId = process.env.PUBLORA_PLATFORM_ID;

1. Draft

const draft = await publora('create-post', {
  method: 'POST',
  body: JSON.stringify({ content: 'Draft from JavaScript', platforms: [platformId] }),
});

No scheduledTime means draft; it will not publish.

2. One-shot schedule

const scheduledTime = new Date(Date.now() + 5 * 60_000).toISOString();
const scheduled = await publora('create-post', {
  method: 'POST',
  idempotencyKey: crypto.randomUUID(),
  body: JSON.stringify({ content: 'Scheduled from JavaScript', platforms: [platformId], scheduledTime }),
});

3. Upload and schedule

Follow the canonical presigned upload sequence: create a draft, request get-upload-url, PUT the file bytes, call complete-media/{mediaFileId}, then schedule with update-post. Each API step uses the publora helper; upload bytes directly to the returned URL without x-publora-key.

await fetch(uploadUrl, {
  method: 'PUT',
  headers: { 'content-type': file.type },
  body: file,
});
 
await publora(`complete-media/${mediaFileId}`, { method: 'POST' });
await publora(`update-post/${postGroupId}`, {
  method: 'PUT',
  idempotencyKey: `schedule-${postGroupId}`,
  body: JSON.stringify({
    status: 'scheduled',
    scheduledTime: new Date(Date.now() + 5 * 60_000).toISOString(),
  }),
});

4. Update

await publora(`update-post/${postGroupId}`, {
  method: 'PUT',
  idempotencyKey: `reschedule-${postGroupId}`,
  body: JSON.stringify({
    status: 'scheduled',
    scheduledTime: new Date(Date.now() + 10 * 60_000).toISOString(),
  }),
});

5. Webhook consumer

import crypto from 'node:crypto';
import express from 'express';
 
const app = express();
app.post('/publora-webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const expected = crypto.createHmac('sha256', process.env.PUBLORA_WEBHOOK_SECRET)
    .update(req.body).digest('hex');
  const received = req.get('x-publora-signature') ?? '';
  const valid = received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
  if (!valid) return res.sendStatus(401);
  const envelope = JSON.parse(req.body.toString('utf8'));
  return res.sendStatus(200);
});

Verify raw bytes before parsing. See Webhooks and the complete OpenAPI surface.