NextPost API

Jadwalkan, publikasikan, dan pantau konten sosial media langsung dari aplikasi Anda. REST API dengan autentikasi API key, response JSON, dan webhook realtime.

Schedule, publish, and monitor social media content straight from your own application. A REST API with API key authentication, JSON responses, and realtime webhooks.

Base URL: https://api.nextpost.id Buat API KeyCreate an API key

Panduan CepatQuick start

  1. Masuk ke Setting โ†’ API, lalu buat API key baru. Key hanya ditampilkan satu kali โ€” simpan di tempat aman.
  2. Hubungkan minimal satu akun sosial di menu Accounts, lalu ambil social_account_id-nya lewat endpoint GET /api/social-accounts.
  3. Kirim request pertama Anda ke POST /api/posts dengan header Authorization: Bearer npk_....
  4. Pantau hasilnya lewat cek status post atau daftarkan webhook agar NextPost yang memberi kabar.
  1. Open Settings โ†’ API and create a new API key. The key is shown only once โ€” store it somewhere safe.
  2. Connect at least one social account under Accounts, then get its social_account_id from the GET /api/social-accounts endpoint.
  3. Send your first request to POST /api/posts with an Authorization: Bearer npk_... header.
  4. Track the result via check post status, or register a webhook and let NextPost notify you.

AutentikasiAuthentication

Semua endpoint yang bertanda ๐Ÿ”’ Butuh API Key memerlukan header Authorization berisi API key Anda dengan skema Bearer. API key selalu diawali npk_.

Every endpoint marked ๐Ÿ”’ API key required needs an Authorization header carrying your API key with the Bearer scheme. API keys always start with npk_.

HeaderHeader
Authorization: Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Perlakukan API key seperti password: jangan pernah menaruhnya di kode frontend, repository publik, atau URL. Kalau key bocor, cabut lewat dashboard dan buat yang baru.

Treat an API key like a password: never put it in frontend code, a public repository, or a URL. If a key leaks, revoke it from the dashboard and create a new one.

NextPost ร— n8n

Paket n8n-nodes-nextpost v0.1.0 tersedia sebagai file TGZ untuk instalasi manual di n8n self-hosted. Belum dipublikasikan di npm atau diverifikasi untuk n8n Cloud; belum tersedia melalui pencarian Community Nodes.

  1. Minta n8n-nodes-nextpost-0.1.0.tgz dan folder examples kepada pengelola NextPost.
  2. Pasang TGZ dalam direktori .n8n/nodes, lalu restart n8n. Pada queue mode, pasang versi yang sama pada main dan seluruh worker. Gunakan Node.js 22.16+ dan volume persisten.
  3. Buat credential NextPost API. Isi API Key dengan npk_... tanpa Bearer; Base URL https://api.nextpost.id tanpa /api.
  4. Jalankan Connection โ†’ Test, lalu impor examples/test-connection.json atau examples/create-draft.json. Pilih credential, platform, dan akun Anda.

n8n-nodes-nextpost v0.1.0 is available as a TGZ for manual installation on self-hosted n8n. It is not published on npm or verified for n8n Cloud, and is not available through Community Nodes search.

  1. Obtain n8n-nodes-nextpost-0.1.0.tgz and the examples folder from your NextPost administrator.
  2. Install the TGZ in .n8n/nodes, then restart n8n. In queue mode install the same version on the main instance and every worker. Use Node.js 22.16+ and persistent storage.
  3. Create a NextPost API credential. Enter npk_... without Bearer and Base URL https://api.nextpost.id without /api.
  4. Run Connection โ†’ Test, then import examples/test-connection.json or examples/create-draft.json. Select your credential, platform, and account.
Docker
docker cp n8n-nodes-nextpost-0.1.0.tgz n8n:/tmp/n8n-nodes-nextpost-0.1.0.tgz
docker exec -u node n8n sh -lc 'mkdir -p /home/node/.n8n/nodes && cd /home/node/.n8n/nodes && npm install --ignore-scripts /tmp/n8n-nodes-nextpost-0.1.0.tgz'
docker restart n8n

Ganti n8n dengan nama container Anda. Operasi tersedia: Connection Test, Social Account Get Many, Post Create/Get/Get Many/Get Status/Delete, Media Upload, serta Comment Get/Get Many/Create Reply Draft/Send Reply.

Draft tidak dipublikasikan. Publish Now masuk antrean; gunakan Get Status untuk hasil tayang. Scheduled At wajib menyertakan timezone. Get Many mendukung pagination. Create Reply Draft belum mengirim balasan; jalankan Send Reply terpisah.

Untuk versi awal gunakan key Admin akun pemilik data; pemetaan post/upload member masih perlu diseragamkan. Hak API dan hak menu tetap berlaku. Simpan key di credential n8n. Retry otomatis pada create/upload/send dapat menimbulkan duplikasi; periksa hasil setelah timeout. Node tidak memasang webhook otomatis.

Panduan lengkap, batas upload, contoh pemetaan, dan penanganan error.

Replace n8n with your container name. Available operations: Connection Test, Social Account Get Many, Post Create/Get/Get Many/Get Status/Delete, Media Upload, and Comment Get/Get Many/Create Reply Draft/Send Reply.

Drafts are not published. Publish Now queues a post; use Get Status for the publishing result. Scheduled At requires a timezone. Get Many supports pagination. Create Reply Draft does not send the reply; run Send Reply separately.

For this initial version use the data-owning account administrator's key; member post/upload workspace mapping still needs alignment. API and menu permissions still apply. Store keys in n8n credentials. Automatic create/upload/send retries can duplicate actions; check results after timeouts. The node does not register webhooks automatically.

Full guide, upload limits, field mappings, and error handling.

๐Ÿ“ Posts

GET /api/posts ๐Ÿ”’ Butuh API Key๐Ÿ”’ API key required

Daftar semua postList all posts

Ambil semua post milik user yang sedang login. Mendukung filter berdasarkan status, platform, dan rentang tanggal.

Retrieve every post belonging to the signed-in user. Supports filtering by status, platform, and date range.

Parameter & FieldParameters & fields

FieldFieldTipeTypeDeskripsiDescription
status string queryopsionaloptional

Filter status: draft | scheduled | processing | published | failed | cancelled

Status filter: draft | scheduled | processing | published | failed | cancelled

platform string queryopsionaloptional

Filter platform: twitter | instagram | facebook | linkedin | pinterest | tiktok | youtube | threads

Platform filter: twitter | instagram | facebook | linkedin | pinterest | tiktok | youtube | threads

from_date datetime queryopsionaloptional

Filter dari tanggal (ISO 8601)

Filter from date (ISO 8601)

to_date datetime queryopsionaloptional

Filter sampai tanggal (ISO 8601)

Filter until date (ISO 8601)

limit number queryopsionaloptional

Jumlah data per halaman (default: 50, max: 100)

Number of records per page (default: 50, max: 100)

offset number queryopsionaloptional

Offset untuk paginasi (default: 0)

Offset for pagination (default: 0)

Contoh RequestExample request

curl -X GET "https://api.nextpost.id/api/posts" \
  -H "Authorization: Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
const response = await fetch("https://api.nextpost.id/api/posts", {
  method: "GET",
  headers: {
    "Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
});

const data = await response.json();
console.log(data);
import requests

headers = {"Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

response = requests.get(
    "https://api.nextpost.id/api/posts",
    headers=headers,
)
print(response.json())
Contoh ResponseExample response
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "user_id": "user_xxx",
      "content": "Halo dari NextPost! ๐Ÿš€ #socialmedia",
      "media_urls": [],
      "platform": "instagram",
      "social_account_id": "660e8400-e29b-41d4-a716-446655440111",
      "scheduled_at": "2026-04-01T08:00:00.000Z",
      "published_at": null,
      "status": "scheduled",
      "platform_options": {},
      "retry_count": 0,
      "created_at": "2026-03-25T09:00:00.000Z"
    }
  ],
  "meta": { "total": 1, "limit": 50, "offset": 0 }
}
GET /api/posts/:id ๐Ÿ”’ Butuh API Key๐Ÿ”’ API key required

Detail satu postGet a single post

Ambil detail post berdasarkan ID. Hanya post milik user sendiri yang bisa diakses.

Retrieve a post by ID. Only your own posts are accessible.

Parameter & FieldParameters & fields

FieldFieldTipeTypeDeskripsiDescription
id string (UUID) pathrequiredrequired

ID post yang ingin diambil

ID of the post to retrieve

Contoh RequestExample request

curl -X GET "https://api.nextpost.id/api/posts/{id}" \
  -H "Authorization: Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
const response = await fetch("https://api.nextpost.id/api/posts/{id}", {
  method: "GET",
  headers: {
    "Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
});

const data = await response.json();
console.log(data);
import requests

headers = {"Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

response = requests.get(
    "https://api.nextpost.id/api/posts/{id}",
    headers=headers,
)
print(response.json())
Contoh ResponseExample response
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "content": "Halo dari NextPost! ๐Ÿš€",
    "platform": "instagram",
    "status": "published",
    "published_at": "2026-03-25T08:00:05.000Z",
    "social_accounts": {
      "platform": "instagram",
      "platform_username": "nextpost_id",
      "platform_profile_url": "https://instagram.com/nextpost_id"
    }
  }
}
POST /api/posts ๐Ÿ”’ Butuh API Key๐Ÿ”’ API key required

Buat post baruCreate a new post

Buat post dengan status draft, scheduled, atau now. HTTP 201 mengembalikan data post yang tersimpan; publikasi dilakukan worker secara async.

draft tidak dipublikasikan. API saat ini mewajibkan scheduled_at untuk draft dan scheduled. Modul n8n mengisi waktu draft otomatis. now masuk antrean segera; gunakan GET /api/posts/:id/status untuk hasil tayang.

Create a post with status draft, scheduled, or now. HTTP 201 returns the saved post in data; a worker publishes asynchronously.

Drafts are not published. The current API requires scheduled_at for draft and scheduled posts. The n8n node supplies the draft timestamp automatically. now queues immediately; use GET /api/posts/:id/status to check the publishing result.

Request BodyRequest body

FieldFieldTipeTypeDeskripsiDescription
content string bodyrequiredrequired

Teks konten post

Post content text

platform string bodyrequiredrequired

Platform: twitter | instagram | facebook | linkedin | pinterest | tiktok | youtube | threads

social_account_id string bodyrequiredrequired

ID akun sosial yang akan digunakan

ID of the social account to publish with

status string bodyopsionaloptional

draft = simpan draft ยท now = antrekan segera ยท scheduled = sesuai jadwal. Default API: scheduled; default modul n8n: draft.

draft = save draft ยท now = queue immediately ยท scheduled = publish at a set time. API default: scheduled; n8n node default: draft.

scheduled_at datetime bodyopsionaloptional

ISO 8601 UTC. API saat ini mewajibkan nilai ini untuk scheduled dan draft; diabaikan untuk now. Modul n8n mengubah timezone ke UTC.

ISO 8601 UTC. Currently required for scheduled and draft posts; ignored for now. The n8n node converts timezones to UTC.

media_urls string[] bodyopsionaloptional

Array URL media (gambar/video)

Array of media URLs (images/videos)

platform_options object bodyopsionaloptional

Opsi tambahan spesifik platform

Additional platform-specific options

Contoh RequestExample request

curl -X POST "https://api.nextpost.id/api/posts" \
  -H "Authorization: Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
  "content": "Halo dari NextPost! ๐Ÿš€ #socialmedia",
  "platform": "instagram",
  "social_account_id": "660e8400-e29b-41d4-a716-446655440111",
  "status": "scheduled",
  "scheduled_at": "2026-04-01T08:00:00Z",
  "media_urls": [],
  "platform_options": {}
}'
const response = await fetch("https://api.nextpost.id/api/posts", {
  method: "POST",
  headers: {
    "Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "content": "Halo dari NextPost! ๐Ÿš€ #socialmedia",
    "platform": "instagram",
    "social_account_id": "660e8400-e29b-41d4-a716-446655440111",
    "status": "scheduled",
    "scheduled_at": "2026-04-01T08:00:00Z",
    "media_urls": [],
    "platform_options": {}
  }),
});

const data = await response.json();
console.log(data);
import requests

headers = {"Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Content-Type": "application/json"}

response = requests.post(
    "https://api.nextpost.id/api/posts",
    headers=headers,
    json={
  "content": "Halo dari NextPost! ๐Ÿš€ #socialmedia",
  "platform": "instagram",
  "social_account_id": "660e8400-e29b-41d4-a716-446655440111",
  "status": "scheduled",
  "scheduled_at": "2026-04-01T08:00:00Z",
  "media_urls": [],
  "platform_options": {}
},
)
print(response.json())
Contoh BodyExample body
{
  "content": "Halo dari NextPost! ๐Ÿš€ #socialmedia",
  "platform": "instagram",
  "social_account_id": "660e8400-e29b-41d4-a716-446655440111",
  "status": "scheduled",
  "scheduled_at": "2026-04-01T08:00:00Z",
  "media_urls": [],
  "platform_options": {}
}
Contoh ResponseExample response
// HTTP 201 โ€” tersimpan, belum berarti published
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "platform": "instagram",
    "status": "scheduled",
    "scheduled_at": "2026-04-16T08:00:00.000Z",
    "published_at": null,
    "platform_post_id": null,
    "error_message": null
  }
}

// HTTP 400 โ€” validasi gagal
{
  "error": "Validation failed",
  "details": { "fieldErrors": { "content": ["Content is required"] } }
}
PATCH /api/posts/:id ๐Ÿ”’ Butuh API Key๐Ÿ”’ API key required

Update postUpdate a post

Update konten, jadwal, atau status post. Hanya post milik sendiri yang bisa diubah. Untuk membatalkan post, set status ke cancelled.

Update a postโ€™s content, schedule, or status. Only your own posts can be modified. To cancel a post, set its status to cancelled.

ParameterParameters

FieldFieldTipeTypeDeskripsiDescription
id string (UUID) pathrequiredrequired

ID post

Post ID

Request BodyRequest body

FieldFieldTipeTypeDeskripsiDescription
content string bodyopsionaloptional

Konten baru

New content

media_urls string[] bodyopsionaloptional

Array URL media baru

New array of media URLs

scheduled_at datetime bodyopsionaloptional

Jadwal baru (ISO 8601)

New schedule (ISO 8601)

status string bodyopsionaloptional

Status baru: scheduled | cancelled

New status: scheduled | cancelled

platform_options object bodyopsionaloptional

Opsi platform baru

New platform options

Contoh RequestExample request

curl -X PATCH "https://api.nextpost.id/api/posts/{id}" \
  -H "Authorization: Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
  "content": "Konten yang sudah diupdate โœจ",
  "scheduled_at": "2026-04-02T10:00:00Z"
}'
const response = await fetch("https://api.nextpost.id/api/posts/{id}", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "content": "Konten yang sudah diupdate โœจ",
    "scheduled_at": "2026-04-02T10:00:00Z"
  }),
});

const data = await response.json();
console.log(data);
import requests

headers = {"Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Content-Type": "application/json"}

response = requests.patch(
    "https://api.nextpost.id/api/posts/{id}",
    headers=headers,
    json={
  "content": "Konten yang sudah diupdate โœจ",
  "scheduled_at": "2026-04-02T10:00:00Z"
},
)
print(response.json())
Contoh BodyExample body
{
  "content": "Konten yang sudah diupdate โœจ",
  "scheduled_at": "2026-04-02T10:00:00Z"
}
Contoh ResponseExample response
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "content": "Konten yang sudah diupdate โœจ",
    "status": "scheduled"
  }
}
DELETE /api/posts/:id ๐Ÿ”’ Butuh API Key๐Ÿ”’ API key required

Hapus postDelete a post

Hapus post. Post yang sedang dalam status processing tidak dapat dihapus.

Delete a post. Posts currently in processing cannot be deleted.

Parameter & FieldParameters & fields

FieldFieldTipeTypeDeskripsiDescription
id string (UUID) pathrequiredrequired

ID post yang akan dihapus

ID of the post to delete

Contoh RequestExample request

curl -X DELETE "https://api.nextpost.id/api/posts/{id}" \
  -H "Authorization: Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
const response = await fetch("https://api.nextpost.id/api/posts/{id}", {
  method: "DELETE",
  headers: {
    "Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
});

const data = await response.json();
console.log(data);
import requests

headers = {"Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

response = requests.delete(
    "https://api.nextpost.id/api/posts/{id}",
    headers=headers,
)
print(response.json())
Contoh ResponseExample response
{ "success": true, "message": "Post deleted successfully" }
POST /api/posts/:id/status ๐Ÿ”’ Butuh API Key๐Ÿ”’ API key required

Cek status postCheck post status

Cek status terbaru dari sebuah post. Berguna untuk polling setelah membuat post โ€” misalnya mengecek apakah post sudah published, masih processing, atau failed. Endpoint ini mengembalikan hanya field yang relevan dengan status, sehingga ringan dan cepat.

Check the latest status of a post. Useful for polling after creating one โ€” for example, to see whether it is already published, still processing, or failed. This endpoint returns only status-related fields, so it stays lightweight and fast.

Parameter & FieldParameters & fields

FieldFieldTipeTypeDeskripsiDescription
id string (UUID) pathrequiredrequired

ID post yang ingin dicek statusnya

ID of the post to check

Contoh RequestExample request

curl -X POST "https://api.nextpost.id/api/posts/{id}/status" \
  -H "Authorization: Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
const response = await fetch("https://api.nextpost.id/api/posts/{id}/status", {
  method: "POST",
  headers: {
    "Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
});

const data = await response.json();
console.log(data);
import requests

headers = {"Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

response = requests.post(
    "https://api.nextpost.id/api/posts/{id}/status",
    headers=headers,
)
print(response.json())
Contoh ResponseExample response
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "published",
  "platform": "instagram",
  "platform_post_id": "insta_abc123",
  "published_at": "2026-04-01T08:00:05.000Z",
  "error_message": null,
  "retry_count": 0,
  "updated_at": "2026-04-01T08:00:05.000Z"
}
POST /api/posts/:id/retry ๐Ÿ”’ Butuh API Key๐Ÿ”’ API key required

Retry post gagalRetry a failed post

Coba ulang publish post yang gagal (failed) atau yang masih scheduled. Status akan direset ke scheduled dan langsung diproses ulang oleh worker. Post yang sedang processing tidak perlu di-retry.

Retry publishing a post that has failed or is still scheduled. Its status resets to scheduled and the worker reprocesses it immediately. Posts currently processing do not need retrying.

Parameter & FieldParameters & fields

FieldFieldTipeTypeDeskripsiDescription
id string (UUID) pathrequiredrequired

ID post yang ingin di-retry

ID of the post to retry

Contoh RequestExample request

curl -X POST "https://api.nextpost.id/api/posts/{id}/retry" \
  -H "Authorization: Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
const response = await fetch("https://api.nextpost.id/api/posts/{id}/retry", {
  method: "POST",
  headers: {
    "Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
});

const data = await response.json();
console.log(data);
import requests

headers = {"Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

response = requests.post(
    "https://api.nextpost.id/api/posts/{id}/retry",
    headers=headers,
)
print(response.json())
Contoh ResponseExample response
{
  "success": true,
  "postId": "550e8400-e29b-41d4-a716-446655440000"
}

๐Ÿ”” Webhooks

POST /your-webhook-url ๐Ÿ”“ Publik๐Ÿ”“ Public

Webhook payloadWebhook payload

NextPost mengirim HTTP POST ke URL webhook Anda setiap kali status post berubah menjadi published atau failed. Kelola webhook di dashboard โ†’ API Information โ†’ Webhooks.

Setiap request menyertakan header:
โ€ข X-NextPost-Event: published | failed
โ€ข X-NextPost-Signature: sha256=... (HMAC-SHA256 dari body, jika secret diisi)
โ€ข User-Agent: NextPost-Webhook/1.0

Timeout: 10 detik. Fire-and-forget โ€” respons diabaikan.

NextPost sends an HTTP POST to your webhook URL whenever a postโ€™s status changes to published or failed. Manage webhooks in the dashboard โ†’ API Information โ†’ Webhooks.

Every request includes these headers:
โ€ข X-NextPost-Event: published | failed
โ€ข X-NextPost-Signature: sha256=... (HMAC-SHA256 of the body, when a secret is set)
โ€ข User-Agent: NextPost-Webhook/1.0

Timeout: 10 seconds. Fire-and-forget โ€” the response is ignored.

Parameter & FieldParameters & fields

FieldFieldTipeTypeDeskripsiDescription
event enum bodyrequiredrequired

"published" | "failed"

"published" | "failed"

post_id uuid bodyrequiredrequired

ID post yang berubah status

ID of the post whose status changed

platform string bodyrequiredrequired

Platform tujuan post (e.g. instagram)

Target platform of the post (e.g. instagram)

status string bodyrequiredrequired

Status akhir: published | failed

Final status: published | failed

published_at datetime? bodyopsionaloptional

Waktu publish (null jika failed)

Publish time (null when failed)

platform_post_id string? bodyopsionaloptional

ID post di platform (null jika failed)

Post ID on the platform (null when failed)

platform_post_url string? bodyopsionaloptional

URL post di platform (null jika failed)

Post URL on the platform (null when failed)

error_message string? bodyopsionaloptional

Pesan error (null jika published)

Error message (null when published)

scheduled_at datetime bodyrequiredrequired

Waktu post dijadwalkan

Time the post was scheduled for

timestamp datetime bodyrequiredrequired

Waktu webhook dikirim (ISO 8601)

Time the webhook was sent (ISO 8601)

Contoh ResponseExample response
// Event: published
{
  "event": "published",
  "post_id": "550e8400-e29b-41d4-a716-446655440000",
  "platform": "instagram",
  "status": "published",
  "published_at": "2026-04-16T08:00:05Z",
  "platform_post_id": "17896129559512345",
  "platform_post_url": null,
  "error_message": null,
  "scheduled_at": "2026-04-16T08:00:00Z",
  "timestamp": "2026-04-16T08:00:06Z"
}

// Event: failed
{
  "event": "failed",
  "post_id": "550e8400-e29b-41d4-a716-446655440001",
  "platform": "twitter",
  "status": "failed",
  "published_at": null,
  "platform_post_id": null,
  "platform_post_url": null,
  "error_message": "HTTP 403: Your account is suspended.",
  "scheduled_at": "2026-04-16T09:00:00Z",
  "timestamp": "2026-04-16T09:00:03Z"
}
POST /your-webhook-url (verifikasi signature) ๐Ÿ”“ Publik๐Ÿ”“ Public

Verifikasi signatureVerifying the signature

Jika Secret diisi saat membuat webhook, setiap request menyertakan header X-NextPost-Signature: sha256=... โ€” HMAC-SHA256 dari raw body request menggunakan secret sebagai key.

Gunakan crypto.timingSafeEqual untuk membandingkan signature agar aman dari timing attack.

If a Secret was set when creating the webhook, every request includes an X-NextPost-Signature: sha256=... header โ€” an HMAC-SHA256 of the raw request body, keyed with that secret.

Use crypto.timingSafeEqual to compare signatures so the check is safe against timing attacks.

Contoh ResponseExample response
// Contoh verifikasi signature (Node.js / Express)
import crypto from 'crypto';

function verifyWebhook(rawBody, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-nextpost-signature'];
  if (!verifyWebhook(req.body, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  const payload = JSON.parse(req.body);
  console.log('Event:', payload.event, 'Post:', payload.post_id);
  res.json({ ok: true });
});

๐Ÿ‘ฅ Social Accounts

GET /api/social-accounts ๐Ÿ”’ Butuh API Key๐Ÿ”’ API key required

List akun terhubungList connected accounts

Ambil semua social accounts milik user beserta statistik akun (followers, following, posts, likes, views, watch time, comments, shares), info quota, dan warning. Statistik disinkronkan berkala oleh metrics-sync โ€” sama dengan yang tampil di menu Accounts.

Retrieve all of the userโ€™s social accounts along with account statistics (followers, following, posts, likes, views, watch time, comments, shares), quota information, and warnings. Statistics are synced periodically by metrics-sync โ€” the same data shown under the Accounts menu.

Contoh RequestExample request

curl -X GET "https://api.nextpost.id/api/social-accounts" \
  -H "Authorization: Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
const response = await fetch("https://api.nextpost.id/api/social-accounts", {
  method: "GET",
  headers: {
    "Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
});

const data = await response.json();
console.log(data);
import requests

headers = {"Authorization": "Bearer npk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

response = requests.get(
    "https://api.nextpost.id/api/social-accounts",
    headers=headers,
)
print(response.json())
Contoh ResponseExample response
{
  "accounts": [
    {
      "id": "660e8400-e29b-41d4-a716-446655440111",
      "platform": "instagram",
      "platform_username": "@nextpost_id",
      "platform_profile_url": "https://instagram.com/nextpost_id",
      "is_active": true,
      "expires_at": "2026-06-01T00:00:00.000Z",
      "created_at": "2026-03-01T10:00:00.000Z",
      "follower_count": 12500,
      "following_count": 320,
      "posts_count": 148,
      "likes_count": 98200,
      "views_count": 1250000,
      "comments_count": 4300,
      "shares_count": 1200,
      "total_watch_seconds": 5400000,
      "account_metrics_synced_at": "2026-07-11T03:00:00.000Z"
    },
    {
      "id": "770e8400-e29b-41d4-a716-446655440222",
      "platform": "twitter",
      "platform_username": "@nextpost_id",
      "platform_profile_url": "https://twitter.com/nextpost_id",
      "is_active": true,
      "expires_at": null,
      "created_at": "2026-03-05T14:30:00.000Z",
      "follower_count": 8100,
      "following_count": 150,
      "posts_count": 96,
      "likes_count": 24100,
      "views_count": 480000,
      "comments_count": 900,
      "shares_count": 350,
      "total_watch_seconds": 0,
      "account_metrics_synced_at": "2026-07-11T03:00:00.000Z"
    }
  ],
  "quota": {
    "used": 2,
    "limit": 10
  },
  "warnings": []
}

โš™๏ธ Lainnya

GET /health ๐Ÿ”“ Publik๐Ÿ”“ Public

Health checkHealth check

Cek status API. Tidak butuh autentikasi.

Check API status. No authentication required.

Contoh RequestExample request

curl -X GET "https://api.nextpost.id/health"
const response = await fetch("https://api.nextpost.id/health", {
  method: "GET",
  headers: {},
});

const data = await response.json();
console.log(data);
import requests

headers = {}

response = requests.get(
    "https://api.nextpost.id/health",
    headers=headers,
)
print(response.json())
Contoh ResponseExample response
{
  "status": "ok",
  "service": "api.nextpost.id",
  "version": "1.0.0",
  "timestamp": "2026-03-25T16:30:00.000Z"
}

๐ŸŽ›๏ธ Platform Options๐ŸŽ›๏ธ Platform options

Setiap platform punya opsi tambahan yang dikirim lewat field platform_options saat membuat atau mengupdate post.

OPTIONS platform_options.twitter

Twitter / X TWEETTHREAD

Kirim di field platform_options saat membuat atau mengupdate post.

Send these in the platform_options field when creating or updating a post.

FieldFieldTipeTypeDeskripsiDescriptionValuesValuesDefaultDefault
post_type string

Tipe post

Post type

TWEET | THREAD TWEET
reply_to string

Tweet ID yang akan dibalas

ID of the tweet to reply to

โ€” โ€”
thread_tweets string[]

List teks tweet untuk thread (jika post_type = THREAD)

List of tweet texts for the thread (when post_type = THREAD)

โ€” โ€”
poll.options string[]

Opsi polling (2โ€“4 opsi)

Poll options (2โ€“4 options)

โ€” โ€”
poll.duration_minutes integer

Durasi polling dalam menit (max 10080 = 7 hari)

Poll duration in minutes (max 10080 = 7 days)

โ€” 1440
Contoh PenggunaanExample usage
"platform_options": {
  "twitter": {
    "post_type": "THREAD",
    "thread_tweets": [
      "1/ Konsistensi adalah kunci utama.",
      "2/ Gunakan visual yang menarik.",
      "3/ Jadwalkan di waktu prime time."
    ]
  }
}
OPTIONS platform_options.instagram

Instagram FEEDSTORYREEL

Kirim di field platform_options saat membuat atau mengupdate post.

Send these in the platform_options field when creating or updating a post.

FieldFieldTipeTypeDeskripsiDescriptionValuesValuesDefaultDefault
post_type string

Tipe post

Post type

FEED | STORY | REEL FEED
location_id string

ID lokasi Facebook/Instagram

Facebook/Instagram location ID

โ€” โ€”
location_name string

Nama lokasi untuk ditampilkan

Location name to display

โ€” โ€”
collaborators string[]

Username kolaborator (Collab Post)

Collaborator username (Collab Post)

โ€” โ€”
Contoh PenggunaanExample usage
"platform_options": {
  "instagram": {
    "post_type": "REEL",
    "location_name": "Jakarta, Indonesia"
  }
}
OPTIONS platform_options.facebook

Facebook FEEDREELSTORY

Kirim di field platform_options saat membuat atau mengupdate post.

Send these in the platform_options field when creating or updating a post.

FieldFieldTipeTypeDeskripsiDescriptionValuesValuesDefaultDefault
post_type string

Tipe post

Post type

FEED | REEL | STORY FEED
page_id string

ID Facebook Page tujuan

Target Facebook Page ID

โ€” โ€”
target_audience string

Visibilitas post

Post visibility

PUBLIC | FRIENDS | CUSTOM PUBLIC
Contoh PenggunaanExample usage
"platform_options": {
  "facebook": {
    "post_type": "FEED",
    "page_id": "123456789012345",
    "target_audience": "PUBLIC"
  }
}
OPTIONS platform_options.tiktok

TikTok VIDEO

Kirim di field platform_options saat membuat atau mengupdate post.

Send these in the platform_options field when creating or updating a post.

FieldFieldTipeTypeDeskripsiDescriptionValuesValuesDefaultDefault
post_type string

Tipe post

Post type

VIDEO VIDEO
publish_type string

DIRECT_POST = publish langsung ยท UPLOAD_CONTENT = simpan sebagai draft di TikTok Creator Studio

DIRECT_POST = publish immediately ยท UPLOAD_CONTENT = save as a draft in TikTok Creator Studio

DIRECT_POST | UPLOAD_CONTENT DIRECT_POST
title string

Judul video (max 150 karakter)

Video title (max 150 characters)

โ€” โ€”
privacy_level string

Visibilitas (diabaikan jika publish_type = UPLOAD_CONTENT)

Visibility (ignored when publish_type = UPLOAD_CONTENT)

PUBLIC | FRIENDS | PRIVATE PUBLIC
disable_comment boolean

Nonaktifkan komentar

Disable comments

โ€” false
disable_duet boolean

Nonaktifkan fitur Duet

Disable Duet

โ€” false
disable_stitch boolean

Nonaktifkan fitur Stitch

Disable Stitch

โ€” false
ai_generated boolean

Wajib true jika konten dibuat oleh AI (COPPA)

Must be true when the content is AI-generated (COPPA)

โ€” false
brand_content boolean

Tandai sebagai konten berbayar/branded

Mark as paid/branded content

โ€” false
Contoh PenggunaanExample usage
"platform_options": {
  "tiktok": {
    "post_type": "VIDEO",
    "publish_type": "DIRECT_POST",
    "title": "Tutorial NextPost",
    "privacy_level": "PUBLIC",
    "disable_comment": false,
    "ai_generated": false,
    "brand_content": false
  }
}
OPTIONS platform_options.youtube

YouTube VIDEOSHORT

Kirim di field platform_options saat membuat atau mengupdate post.

Send these in the platform_options field when creating or updating a post.

FieldFieldTipeTypeDeskripsiDescriptionValuesValuesDefaultDefault
post_type string

Tipe post

Post type

VIDEO | SHORT VIDEO
title string

Judul video (wajib untuk YouTube)

Video title (required for YouTube)

โ€” โ€”
description string

Deskripsi video

Video description

โ€” โ€”
tags string[]

Tag/keyword video

Video tags/keywords

โ€” โ€”
category_id string

ID kategori YouTube

YouTube category ID

โ€” โ€”
privacy_status string

Visibilitas. Gunakan "private" sebagai pengganti draft โ€” video tidak terlihat publik sampai diubah manual

Visibility. Use "private" in place of a draft โ€” the video stays hidden from the public until changed manually

public | private | unlisted public
made_for_kids boolean

Wajib diisi sesuai COPPA

Required for COPPA compliance

โ€” false
enable_comments boolean

Aktifkan komentar

Enable comments

โ€” true
enable_embedding boolean

Aktifkan embedding

Enable embedding

โ€” true
license string

Lisensi video

Video license

youtube | creativeCommon youtube
Contoh PenggunaanExample usage
"platform_options": {
  "youtube": {
    "post_type": "VIDEO",
    "title": "Tutorial Social Media Marketing 2026",
    "description": "Di video ini kita bahas strategi...",
    "tags": ["social media", "marketing"],
    "privacy_status": "public",
    "made_for_kids": false
  }
}
OPTIONS platform_options.threads

Threads POST

Kirim di field platform_options saat membuat atau mengupdate post.

Send these in the platform_options field when creating or updating a post.

FieldFieldTipeTypeDeskripsiDescriptionValuesValuesDefaultDefault
post_type string

Tipe post

Post type

POST POST
link string

URL link yang dilampirkan ke post

URL attached to the post

โ€” โ€”
reply_control string

Siapa yang bisa membalas

Who can reply

EVERYONE | MENTIONED | FOLLOWING EVERYONE
Contoh PenggunaanExample usage
"platform_options": {
  "threads": {
    "post_type": "POST",
    "link": "https://nextpost.id",
    "reply_control": "EVERYONE"
  }
}

โš ๏ธ Kode Errorโš ๏ธ Error codes

Error dikembalikan sebagai JSON dengan field error, dan kadang details untuk kesalahan validasi per-field.

Errors are returned as JSON with an error field, and sometimes details for per-field validation problems.

StatusStatusNamaNamePenyebab umumCommon cause
400 Bad Request

Body atau parameter tidak valid. Cek field details untuk detail per-field.

Invalid body or parameter. Check the details field for per-field information.

401 Unauthorized

API key tidak dikirim, salah, sudah dicabut, atau kedaluwarsa.

The API key is missing, incorrect, revoked, or expired.

403 Forbidden

Resource bukan milik Anda, atau di luar kuota paket berlangganan.

The resource is not yours, or it exceeds your subscription plan quota.

404 Not Found

Post atau akun sosial dengan ID tersebut tidak ditemukan.

No post or social account exists with that ID.

429 Too Many Requests

Rate limit terlampaui. Cek header Retry-After sebelum mencoba lagi.

Rate limit exceeded. Check the Retry-After header before retrying.

5xx Server Error

Gangguan di sisi NextPost. Coba ulang dengan exponential backoff.

A problem on the NextPost side. Retry with exponential backoff.

Rate LimitRate limits

Request dibatasi per API key. Kalau limit terlampaui, API membalas 429 Too Many Requests beserta header Retry-After (detik) dan X-RateLimit-Reset.

Untuk pengiriman massal, beri jeda antar request dan gunakan exponential backoff saat menerima 429 atau 5xx โ€” jangan retry ketat dalam loop.

Requests are limited per API key. When the limit is exceeded the API replies with 429 Too Many Requests plus Retry-After (in seconds) and X-RateLimit-Reset headers.

For bulk sending, space your requests out and use exponential backoff on a 429 or 5xx โ€” do not retry tightly in a loop.

Butuh bantuan?Need help?

Ada pertanyaan soal integrasi atau menemukan perilaku yang tidak sesuai dokumentasi ini? Hubungi kami di [email protected] atau lewat halaman kontak.

Questions about integrating, or found behaviour that does not match these docs? Email us at [email protected] or use the contact page.