Panduan CepatQuick start
- Masuk ke Setting โ API, lalu buat API key baru. Key hanya ditampilkan satu kali โ simpan di tempat aman.
- Hubungkan minimal satu akun sosial di menu Accounts, lalu ambil
social_account_id-nya lewat endpoint GET /api/social-accounts. - Kirim request pertama Anda ke POST /api/posts dengan header
Authorization: Bearer npk_.... - Pantau hasilnya lewat cek status post atau daftarkan webhook agar NextPost yang memberi kabar.
- Open Settings โ API and create a new API key. The key is shown only once โ store it somewhere safe.
- Connect at least one social account under Accounts, then get its
social_account_idfrom the GET /api/social-accounts endpoint. - Send your first request to POST /api/posts with an
Authorization: Bearer npk_...header. - 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_.
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.
- Minta
n8n-nodes-nextpost-0.1.0.tgzdan folderexampleskepada pengelola NextPost. - 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. - Buat credential NextPost API. Isi API Key dengan
npk_...tanpa Bearer; Base URLhttps://api.nextpost.idtanpa/api. - Jalankan Connection โ Test, lalu impor
examples/test-connection.jsonatauexamples/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.
- Obtain
n8n-nodes-nextpost-0.1.0.tgzand theexamplesfolder from your NextPost administrator. - 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. - Create a NextPost API credential. Enter
npk_...without Bearer and Base URLhttps://api.nextpost.idwithout/api. - Run Connection โ Test, then import
examples/test-connection.jsonorexamples/create-draft.json. Select your credential, platform, and account.
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
/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
| FieldField | TipeType | DeskripsiDescription | |
|---|---|---|---|
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())
{
"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 }
}
/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
| FieldField | TipeType | DeskripsiDescription | |
|---|---|---|---|
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())
{
"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"
}
}
}
/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
| FieldField | TipeType | DeskripsiDescription | |
|---|---|---|---|
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 |
|
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())
{
"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": {}
}
// 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"] } }
}
/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
| FieldField | TipeType | DeskripsiDescription | |
|---|---|---|---|
id |
string (UUID) | pathrequiredrequired | ID post Post ID |
Request BodyRequest body
| FieldField | TipeType | DeskripsiDescription | |
|---|---|---|---|
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())
{
"content": "Konten yang sudah diupdate โจ",
"scheduled_at": "2026-04-02T10:00:00Z"
}
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"content": "Konten yang sudah diupdate โจ",
"status": "scheduled"
}
}
/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
| FieldField | TipeType | DeskripsiDescription | |
|---|---|---|---|
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())
{ "success": true, "message": "Post deleted successfully" }
/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
| FieldField | TipeType | DeskripsiDescription | |
|---|---|---|---|
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())
{
"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"
}
/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
| FieldField | TipeType | DeskripsiDescription | |
|---|---|---|---|
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())
{
"success": true,
"postId": "550e8400-e29b-41d4-a716-446655440000"
}
๐ Webhooks
/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
| FieldField | TipeType | DeskripsiDescription | |
|---|---|---|---|
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) |
// 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"
}
/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 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
/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())
{
"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
/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())
{
"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.
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.
| FieldField | TipeType | DeskripsiDescription | ValuesValues | DefaultDefault |
|---|---|---|---|---|
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 |
"platform_options": {
"twitter": {
"post_type": "THREAD",
"thread_tweets": [
"1/ Konsistensi adalah kunci utama.",
"2/ Gunakan visual yang menarik.",
"3/ Jadwalkan di waktu prime time."
]
}
}
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.
| FieldField | TipeType | DeskripsiDescription | ValuesValues | DefaultDefault |
|---|---|---|---|---|
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) |
โ | โ |
"platform_options": {
"instagram": {
"post_type": "REEL",
"location_name": "Jakarta, Indonesia"
}
}
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.
| FieldField | TipeType | DeskripsiDescription | ValuesValues | DefaultDefault |
|---|---|---|---|---|
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 |
"platform_options": {
"facebook": {
"post_type": "FEED",
"page_id": "123456789012345",
"target_audience": "PUBLIC"
}
}
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.
| FieldField | TipeType | DeskripsiDescription | ValuesValues | DefaultDefault |
|---|---|---|---|---|
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 |
"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
}
}
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.
| FieldField | TipeType | DeskripsiDescription | ValuesValues | DefaultDefault |
|---|---|---|---|---|
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 |
"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
}
}
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.
| FieldField | TipeType | DeskripsiDescription | ValuesValues | DefaultDefault |
|---|---|---|---|---|
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 |
"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.
| StatusStatus | NamaName | Penyebab umumCommon cause |
|---|---|---|
400 |
Bad Request | Body atau parameter tidak valid. Cek field Invalid body or parameter. Check the |
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 Rate limit exceeded. Check the |
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.