RingkasanIkhtisar API

Ringkasan

Ikhtisar API

Setiap endpoint Sofia API v1 dengan parameter, scope, dan contohnya, serta playground untuk mencoba masing-masing dengan kunci API Anda sendiri.

URL dasar https://api.sofia-post.com/api · Dokumen OpenAPI

Sofia API memberi kode Anda akses ke akun Sofia Anda: usaha di Workspace Anda, jaringan terhubungnya, pustaka mediannya, postingannya, dan statistiknya. Ini adalah API REST lewat HTTPS; permintaan dan responsnya berformat JSON. API ini memungkinkan Anda untuk:

  • Menerbitkan: sekarang, pada tanggal tertentu, atau sebagai draf, ke satu atau beberapa jaringan sekaligus.
  • Memeriksa sebelum menerbitkan: simulasi memberi tahu apakah setiap jaringan akan menerima postingan, tanpa menulis apa pun.
  • Mengelola media: unggah file atau impor dari URL ke pustaka media sebuah usaha.
  • Memantau postingan: baca status setiap jaringan, tautan permanennya, atau alasan kegagalan. Webhook bertanda tangan juga bisa memberi tahu Anda.
  • Membaca statistik: angka terbaru yang dikumpulkan Sofia untuk setiap akun terhubung.
  • Menghubungkan jaringan: buat tautan terhosting yang memungkinkan pemilik menghubungkan jaringan yang belum ada.

SDK dan integrasi

  • CLI `sofia`: CLI, yang dipublikasikan di npm dengan nama sofia-post, untuk mengendalikan Sofia dari terminal.
  • Server MCP: hubungkan Sofia ke agen AI Anda.
  • Zapier: integrasi Sofia terhubung dengan kunci pribadi Anda. Integrasi ini menyediakan pemicu “Post Published” dan “Post Failed”, tindakan “Create Post” (menerbitkan, menjadwalkan, atau menyimpan draf), dan pencarian “Find Post”. Belum diajukan ke direktori publik Zapier.

Autentikasi

Setiap panggilan membawa token Bearer di header Authorization. Sofia membaca ulang hak yang melekat padanya pada setiap panggilan: orang yang dikeluarkan dari sebuah Workspace, atau otorisasi yang dicabut, menghentikan token sejak permintaan berikutnya.

Ada dua cara untuk mengautentikasi:

MetodeUntukToken
Kunci pribadiMengotomatiskan akun Anda sendiri, skrip, agensofia_pk_live_…, berlaku hingga kedaluwarsa
OAuth, kode otorisasi + PKCEProduk yang bertindak untuk penggunanya, di Workspace pilihan merekasofia_live_at_…, satu jam, dapat diperbarui
OAuth, client credentialsSalah satu server Anda yang mengotomatiskan Workspace milik Andasofia_live_at_…, satu jam

Kunci API

Jika Anda mengotomatiskan Workspace Anda sendiri, kunci pribadi sudah cukup. Di aplikasi Sofia, buka Pengaturan › API, tab Akses pribadi, dan buat kunci. Pilih nama, masa berlaku, dan izinnya. Kunci hanya ditampilkan sekali: salin dan simpan di brankas rahasia, jangan pernah di kode Anda.

Buat kunci di Pengaturan › API › Akses pribadi. Kunci bertindak untuk Anda di semua Workspace Anda: usaha yang Anda sebut menentukan Workspace-nya, dan peran Anda di sana menentukan apa yang bisa dilakukan kunci.

Kirim kunci di header Authorization, sebagai token Bearer:

curl https://api.sofia-post.com/api/v1/establishments \
  -H "Authorization: Bearer sofia_pk_live_…"

`GET /v1/me` memberi tahu untuk siapa kunci bertindak, Workspace-nya, dan izinnya.

Panggilan tanpa izin (scope) yang diperlukan menjawab 403 insufficient_scope.

Token OAuth2

Untuk produk SaaS yang bertindak untuk penggunanya di Workspace mereka sendiri, daftarkan klien OAuth: setiap orang mengizinkan aplikasi Anda di Workspace pilihannya. Token akses OAuth diawali sofia_live_at_…, berlaku satu jam, dan dipakai dengan cara yang sama:

curl https://api.sofia-post.com/api/v1/establishments \
  -H "Authorization: Bearer sofia_live_at_…"

Anda membuat aplikasi yang akan dihubungkan akun Sofia lain? Alur authorization code dengan PKCE, client credentials, dan scope-nya dijelaskan di OAuth2.

URL dasar

Setiap endpoint berada di bawah satu URL dasar:

https://api.sofia-post.com/api/v1

Batas laju

Sofia API menghitung permintaan pada tiga jendela: 15 menit, 24 jam, dan 30 hari.

Token15 menit24 jam30 hari
Kunci pribadi (per akun)1501.00010.000
Klien OAuth10050015.000
Klien OAuth, per orang yang mengizinkan (hingga 1.000)+10+25+100

Header

Setiap respons memberi tahu sisanya, dalam format IETF:

RateLimit: "15m";r=144;t=43, "24h";r=994;t=13543, "30d";r=9994;t=13543
RateLimit-Policy: "15m";q=150;w=900, "24h";q=1000;w=86400, "30d";q=10000;w=2592000

r adalah jumlah permintaan yang tersisa, t detik sebelum jendela diatur ulang, q kuota, dan w jendela dalam detik.

Saat sebuah jendela penuh

Responsnya 429 rate_limit_exceeded, dengan header Retry-After dan jendela yang habis di details. Tunggu selama jeda itu sebelum mencoba lagi.

Menggunakan API secara efisien

  • Daftarkan webhook daripada memeriksa postingan berulang-ulang.
  • Gunakan limit hingga 100 untuk membaca daftar dengan lebih sedikit halaman.
  • Simpan di cache apa yang jarang berubah: platform, usaha, akun terhubung.

Kesalahan

Setiap kesalahan dijawab dengan status HTTP dan amplop JSON yang sama. code adalah kontrak yang dibaca kode Anda; message ditulis untuk manusia dan bisa berubah.

{
  "error": {
    "code": "invalid_request",
    "message": "The request is invalid",
    "details": [
      { "field": "targets[0].text", "code": "required", "message": "targets[0].text is required" }
    ],
    "docUrl": "https://www.sofia-post.com/developers/errors#invalid_request",
    "requestId": "2aab5943-6333-4caf-8478-25a85ebd4abf"
  }
}
  • details menjelaskan lebih banyak: kolom yang ditolak, alasan sebuah jaringan, jendela batas yang habis.
  • docUrl mengarah ke penjelasan kode itu di halaman ini.
  • requestId mengidentifikasi permintaan: sampaikan ke dukungan.

Kode kesalahan

StatusKodeArti
400invalid_requestBody, query, atau parameter tidak valid. Satu rincian per field yang ditolak: field, code (required, is_string, max…), dan message.
400invalid_jsonBody bukan JSON yang valid.
400invalid_cursorKursor tidak dikembalikan oleh Sofia API.
400webhook_url_invalidAlamat webhook bukan https, atau mengarah ke alamat privat.
400webhook_event_invalidEvent webhook tidak dikenal.
400application_name_invalidPengaturan › API: nama klien tidak ada atau terlalu panjang.
400application_profile_invalidPengaturan › API: ada kolom profil klien yang tidak valid; rinciannya menyebutkannya.
400logo_invalidPengaturan › API: logo ditolak (minimal 180×180 px, PNG, JPEG, atau WebP, maksimal 2 MB).
401invalid_tokenToken tidak ada, tidak dikenal, kedaluwarsa, atau dicabut, atau orang di baliknya kehilangan hak yang dibawanya. Lihat header WWW-Authenticate.
401unauthorizedAutentikasi diperlukan.
402subscription_requiredPenulisan live (termasuk dry run) memerlukan langganan aktif atau masa percobaan.
403insufficient_scopeToken tidak memiliki scope endpoint; rinciannya menyebutkannya.
403insufficient_rolePeran Anda di Workspace ini tidak mengizinkan tindakan ini.
403live_mode_requiredPenulisan nyata dengan token uji.
403route_closed_to_applicationsEndpoint ini tidak terbuka untuk aplikasi.
403forbiddenAkses ditolak.
403session_requiredPengaturan › API: tindakan ini memerlukan sesi Sofia, bukan token.
403impersonation_forbiddenPengaturan › API: tindakan ini ditolak dalam sesi pinjaman.
403workspace_owner_requiredHanya pemilik Workspace yang dapat melakukannya.
403workspace_member_requiredAnda bukan anggota Workspace ini.
404route_not_foundTidak ada endpoint yang menjawab metode dan path ini.
404establishment_not_foundUsaha tidak dikenal, atau di luar jangkauan token.
404media_not_foundMedia tidak dikenal, atau di luar jangkauan token.
404post_not_foundPostingan tidak dikenal, atau di luar jangkauan token.
404webhook_not_foundWebhook tidak dikenal, atau milik aplikasi lain.
404not_foundSumber daya tidak ada.
404application_not_foundPengaturan › API: klien tidak dikenal.
404grant_not_foundOtorisasi tidak dikenal, atau sudah dicabut.
404personal_key_not_foundPengaturan › API: kunci pribadi tidak dikenal.
405method_not_allowedMetode ini tidak diizinkan pada endpoint ini.
409post_in_flightSebuah jaringan sedang mengirim postingan: coba hapus lagi sebentar lagi.
409post_not_editableSebuah jaringan sudah mengirim postingan: tidak dapat diedit lagi.
409account_already_connectedJaringan ini sudah terhubung ke usaha.
409webhook_limit_reachedAplikasi sudah memiliki 10 webhook.
409idempotency_in_progressPermintaan pertama dengan Idempotency-Key ini masih berjalan.
409conflictPermintaan bertentangan dengan keadaan sumber daya saat ini.
409scope_removal_forbiddenPengaturan › API: izin klien dapat ditambahkan tetapi tidak dapat dihapus.
409public_client_has_no_secretPengaturan › API: klien publik tidak memiliki secret.
413payload_too_largeFile melebihi batas unggah.
415unsupported_media_typeTipe konten tidak didukung.
422post_refusedSebuah jaringan, usaha, atau paket Anda akan menolak postingan. Satu rincian per alasan, masing-masing dengan message-nya.
422media_import_refusedMedia tidak dapat diimpor dari URL ini; rinciannya menyebut alasannya.
422media_upload_refusedFile yang diunggah bukan gambar atau video yang didukung.
422platform_not_offeredJaringan ini tidak ditawarkan untuk dihubungkan.
422idempotency_key_reusedIdempotency-Key ini dipakai dengan body yang berbeda.
422unprocessable_entityPermintaan dipahami tetapi tidak dapat diproses.
429rate_limit_exceededJendela batas laju penuh: tunggu sesuai Retry-After.

Alasan sebuah postingan ditolak

post_refused mendaftar setiap alasan di details[].code:

KodeArti
unsupported_platformJaringan ini tidak didukung.
duplicate_platformJaringan yang sama disebut dua kali.
unsupported_formatJaringan ini tidak menawarkan format ini.
caption_too_longTeks terlalu panjang (max, actual).
too_many_hashtagsTerlalu banyak hashtag (max, actual).
too_many_mentionsTerlalu banyak mention (max, actual).
too_many_thread_postsThread terlalu panjang (max, actual).
too_many_mediaTerlalu banyak media (max, actual).
media_mix_refusedFoto dan video tidak dapat dicampur di jaringan ini.
media_requiredJaringan ini memerlukan foto atau video.
media_type_refusedJaringan ini tidak menerima jenis media ini.
scheduled_in_pastscheduledAt sudah lewat.
scheduled_at_invalidPostingan terjadwal memerlukan scheduledAt di masa depan.
account_not_connectedTidak ada akun yang terhubung di jaringan ini untuk usaha ini.
account_ambiguousBeberapa akun terhubung di jaringan ini: sebutkan satu dengan accountId.
media_not_foundMedia tidak ada di pustaka usaha ini.
media_url_invalidURL media harus berupa alamat https publik.
platform_unavailableJaringan ini belum dibuka di Sofia.
publication_quota_exceededKuota publikasi paket Anda telah tercapai.

Menangani kesalahan

  • Dasarkan logika Anda pada code, jangan pernah pada message.
  • Coba lagi 429 setelah Retry-After, dan 5xx dengan backoff eksponensial.
  • Jangan pernah mengulang 4xx yang sama persis: perbaiki dulu permintaannya.
  • Catat requestId pada setiap kegagalan.

Paginasi

Daftar (GET /v1/posts, GET /v1/media) dikembalikan dengan yang terbaru lebih dulu, satu halaman sekali. limit menentukan ukuran halaman, dari 1 sampai 100 (bawaan 20).

{
  "data": [ … ],
  "nextCursor": "WyIyMDI2LTEwLTI3VDE1OjExOjU5LjAxN1oiLCIx…"
}

Teruskan nextCursor sebagai cursor untuk membaca halaman berikutnya. Jika nextCursor tidak ada, Anda sudah sampai di akhir.

let cursor;
do {
  const url = new URL('https://api.sofia-post.com/api/v1/posts');
  url.searchParams.set('limit', '100');
  if (cursor) url.searchParams.set('cursor', cursor);
  const page = await globalThis.fetch(url, { headers: { Authorization: `Bearer ${key}` } }).then((r) => r.json());
  handle(page.data);
  cursor = page.nextCursor;
} while (cursor);

Kursor bersifat buram: jangan pernah membuat atau mengubahnya. Kursor yang tidak dikembalikan Sofia menjawab 400 invalid_cursor.

Idempotensi

Kesalahan jaringan bisa membuat Anda ragu apakah sebuah postingan sudah dibuat. Kirim header Idempotency-Key dengan POST /v1/posts dan POST /v1/media, lalu coba lagi dengan kunci yang sama: Sofia menjawab apa yang dijawabnya pertama kali, dan tidak membuat apa pun secara ganda.

curl -X POST https://api.sofia-post.com/api/v1/posts \
  -H "Authorization: Bearer $SOFIA_API_KEY" \
  -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -d @post.json
  • Gunakan kunci acak baru (UUID) untuk setiap postingan baru, dan kunci yang sama untuk setiap percobaan ulang postingan itu.
  • Kunci yang sama dengan isi berbeda menjawab 422 idempotency_key_reused.
  • Selama permintaan pertama masih berjalan, kunci yang sama menjawab 409 idempotency_in_progress: coba lagi sebentar lagi.

Mode uji dan simulasi

Simulasi. Tambahkan ?dry_run=true ke POST /v1/posts: Sofia menjalankan pemeriksaan postingan sungguhan (aturan setiap jaringan, akun terhubung, media, tanggal, dan paket Anda) tanpa menyimpan atau mengirim apa pun. Rincian respons ada di halaman Menerbitkan.

Mode uji. Aplikasi yang dibuat dalam mode test (token sofia_test_at_…) membaca Workspace asli Anda tetapi tidak pernah menulis di sana: postingannya disimulasikan dan dinilai dengan aturan yang sama, dan setiap penulisan sungguhan menjawab 403 live_mode_required. Kunci dan klien yang dibuat di Pengaturan › API berada dalam mode live; gunakan simulasi untuk memeriksa tanpa menerbitkan.

OAuth

Akun

Platform

Usaha

Media

Postingan

Webhook