Referensi API
Bangun integrasi kustom dengan REST API Asyntai
Diperlukan Paket Berbayar: Akses API tersedia pada paket Starter, Standard, dan Pro. Lihat harga
Ringkasan
The Asyntai API allows you to integrate AI-powered customer support into any application. Send messages and receive intelligent responses grounded in your website content and knowledge base.
Autentikasi
Semua permintaan API memerlukan autentikasi menggunakan kunci API Anda. Anda dapat mendapatkan kunci API dari halaman Pengaturan API.
Sertakan kunci API Anda dalam permintaan menggunakan salah satu metode berikut:
- Header Authorization (disarankan):
Authorization: Bearer YOUR_API_KEY - Header X-API-Key:
X-API-Key: YOUR_API_KEY
Jaga kerahasiaan kunci API Anda. Siapa pun yang memiliki kunci Anda dapat mengakses akun Anda melalui API. Jangan pernah mengeksposnya di kode sisi klien.
URL Dasar
https://asyntai.com/api/v1/
Endpoint
POST /chat/
Kirim pesan dan terima respons yang dihasilkan AI.
Isi Permintaan
{
"message": "What are your business hours?",
"session_id": "user_123", // optional
"website_id": 1 // optional
}
| Parameter | Tipe | Wajib | Deskripsi |
|---|---|---|---|
message |
string | Ya | Pesan pengguna untuk dikirim ke AI |
session_id |
string | Tidak | Pengidentifikasi unik untuk percakapan. Gunakan session_id yang sama untuk mempertahankan riwayat percakapan. |
website_id |
integer | Tidak | ID situs web tertentu. Jika tidak disediakan, gunakan situs web utama Anda. |
Respons
{
"success": true,
"response": "Our business hours are Monday-Friday, 9 AM to 5 PM EST.",
"session_id": "user_123"
}
Contoh (cURL)
curl -X POST https://asyntai.com/api/v1/chat/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"message": "What are your business hours?", "session_id": "user_123"}'
Contoh (Python)
import requests
response = requests.post(
"https://asyntai.com/api/v1/chat/",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
json={
"message": "What are your business hours?",
"session_id": "user_123"
}
)
data = response.json()
print(data["response"])
Contoh (JavaScript)
const response = await fetch("https://asyntai.com/api/v1/chat/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
message: "What are your business hours?",
session_id: "user_123"
})
});
const data = await response.json();
console.log(data.response);
GET /websites/
Daftar semua situs web yang terkait dengan akun Anda.
Respons
{
"success": true,
"websites": [
{
"id": 1,
"name": "My Website",
"domain": "example.com",
"is_primary": true
}
]
}
Contoh (cURL)
curl https://asyntai.com/api/v1/websites/ \
-H "Authorization: Bearer YOUR_API_KEY"
POST /websites/
Create a new AI agent. This does the same thing as adding a website in your dashboard: it makes the agent, reads your site, and writes the first draft of the AI instructions.
Use this to set up customers from your own software. You get back the widget ID and the code to put on the website.
Isi Permintaan
| Kolom | Tipe | Deskripsi |
|---|---|---|
domain |
string | Required. The website address, for example example.com |
name |
string | Optional. A display name for the agent. Useful when one website has several agents. |
crawl |
boolean | Optional, true by default. Set it to false to create the agent without reading the website. Nothing is crawled and no instructions are written. |
force |
boolean | Optional, false by default. Set it to true to add a website you already have. The copy is stored with a number after it. |
Respons
{
"success": true,
"website": {
"id": 42,
"domain": "example.com",
"name": "Support agent",
"widget_id": "asyntai_ab12cd34ef56",
"is_primary": true,
"crawl_started": true,
"instructions_status": "generating",
"job_id": "8f2c1e90-..."
},
"embed_code": "<script>...</script>"
}
Contoh (cURL)
curl -X POST https://asyntai.com/api/v1/websites/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"domain": "example.com", "name": "Support agent"}'
Reading a website takes a few minutes, so this call answers straight away. Check when the agent is ready with the next endpoint.
Errors
| Code | Meaning |
|---|---|
403 |
You have reached the number of websites your plan allows. The answer tells you the limit. |
409 |
Your account already has this website. Send force as true to add it again. |
GET /websites/{id}/
Get one website and see whether it is ready. Use this after you create an agent, to wait until the website has been read and the AI instructions are written.
Respons
{
"success": true,
"website": {
"id": 42,
"domain": "example.com",
"name": "Support agent",
"widget_id": "asyntai_ab12cd34ef56",
"is_primary": true,
"created_at": "2026-08-11T09:12:00+00:00",
"ready": true,
"instructions": {
"status": "completed",
"has_instructions": true,
"characters": 3421
},
"crawl": {
"job_id": "8f2c1e90-...",
"status": "completed",
"pages_crawled": 47,
"pages_found": 50,
"max_pages": 50,
"completed_at": "2026-08-11T09:15:31+00:00",
"error": ""
},
"knowledge_items": 47
},
"embed_code": "<script>...</script>"
}
The ready field is true when nothing is still running. A crawl that failed also counts as ready, because it has finished. Look at the crawl status to see what happened.
Contoh (cURL)
curl https://asyntai.com/api/v1/websites/42/ \
-H "Authorization: Bearer YOUR_API_KEY"
GET PATCH /websites/{id}/settings/
Read or change the chat widget settings for one website. These are the same settings you see on the Customize page: colours, the name of the assistant, the first message, lead capture, and everything else.
Reading the settings
A GET request returns every setting with its current value, plus a locked list. Locked shows the settings your plan cannot change, and which plans they need.
{
"success": true,
"settings": {
"ai_support_name": "AI Assistant",
"widget_color": "#6366f1",
"initial_message": "Hi, how can I help you?",
"hide_branding": false,
"...": "..."
},
"locked": {
"hide_branding": ["pro", "enterprise"],
"widget_style": ["pro", "enterprise"]
}
}
Changing the settings
A PATCH request changes only the settings you send. Everything you leave out stays as it is.
curl -X PATCH https://asyntai.com/api/v1/websites/42/settings/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ai_support_name": "Ava", "widget_color": "#0f172a", "use_emoji": true}'
{
"success": true,
"updated": ["ai_support_name", "use_emoji", "widget_color"],
"settings": { "...": "..." },
"locked": { "...": "..." }
}
Plans
Each setting needs its own plan, the same as in the dashboard. For example, hiding the Asyntai branding needs the Pro plan, and voice input needs Standard.
| Plan needed | Pengaturan | Examples |
|---|---|---|
| Any paid plan | 25 | widget_color, ai_support_name, initial_message |
| Starter dan di atasnya | 22 | profile_picture, conversation_starters_enabled |
| Standard dan di atasnya | 25 | speech_to_text_enabled, image_vision_enabled, escalation_enabled |
| Pro | 6 | hide_branding, widget_style |
If you send a setting your plan does not allow, the whole request is refused with code 403 and nothing is saved. The same happens if any value is wrong, for example a colour that is not a hex code. Your settings never end up half changed.
GET PUT /websites/{id}/instructions/
Read or replace the AI instructions for one website. These are the rules that tell the assistant who it is, what it may say, and what it must not say. They are the same instructions you edit in the dashboard.
Reading
{
"success": true,
"instructions": "You are the support agent for Acme Tools...",
"characters": 1979,
"version": 7,
"mode": "instructions",
"ask_questions": true,
"generation_status": "completed",
"being_edited_by": null
}
Replacing
A PUT request replaces the whole text, the same as saving in the dashboard. There is no append mode. To add a paragraph, read the instructions, add your text, then write it back.
curl -X PUT https://asyntai.com/api/v1/websites/42/instructions/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"instructions": "You are the support agent for Acme Tools...", "version": 7}'
Isi Permintaan
| Kolom | Tipe | Deskripsi |
|---|---|---|
instructions |
string | Required. The complete new text. It replaces everything that was there. |
version |
number | Optional but recommended. The version you read. If somebody changed the instructions since then, your write is refused instead of overwriting their work. |
mode |
string | Optional. Either instructions or general. |
ask_questions |
boolean | Optional. Whether the assistant asks a follow-up question at the end of its answers. |
force |
boolean | Optional, false by default. Needed only when your new text is less than half the length of the current text. |
How your instructions are protected
Instructions can take hours to write, so a write can be refused to protect them:
| Code | Meaning |
|---|---|
400 |
Your new text is less than half the length of the current text. This catches a script that sends empty or cut-off text over instructions somebody spent hours on. Send force as true if you meant it. |
409 |
The instructions changed after you read them. Read them again, apply your change, then write. |
423 |
Somebody is editing the instructions in the dashboard right now. The answer tells you who. Try again in a couple of minutes. |
Every change also saves a copy of the previous text, so an earlier version can always be restored from the dashboard.
GET /conversations/
Ambil riwayat percakapan untuk sesi tertentu.
Parameter Kueri
| Parameter | Tipe | Wajib | Deskripsi |
|---|---|---|---|
session_id |
string | Ya | ID sesi untuk mengambil riwayat |
limit |
integer | Tidak | Jumlah pesan maksimum yang dikembalikan (default: 50, maks: 100) |
Respons
{
"success": true,
"session_id": "user_123",
"messages": [
{
"role": "user",
"content": "What are your business hours?",
"timestamp": "2024-01-15T10:30:00Z"
},
{
"role": "assistant",
"content": "Our business hours are Monday-Friday, 9 AM to 5 PM EST.",
"timestamp": "2024-01-15T10:30:01Z",
"sender_type": "ai",
"agent_name": null,
"response_time_ms": 1840.5
}
]
}
Pertanyaan dan jawabannya disimpan dalam satu catatan, sehingga keduanya membawa timestamp yang sama. Jangan mengurangkan yang satu dari yang lain untuk mengukur kecepatan balasan, karena hasilnya selalu nol. Gunakan response_time_ms, yaitu waktu sebenarnya yang dibutuhkan jawaban, dalam milidetik.
sender_type bernilai ai saat chatbot menjawab, dan human saat salah satu agen Anda mengambil alih obrolan. agent_name berisi nama tampilan agen tersebut.
Contoh (cURL)
curl "https://asyntai.com/api/v1/conversations/?session_id=user_123&limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"
GET /sessions/
Daftar sesi chat terbaru Anda. Gunakan ini untuk menemukan ID sesi, yang kemudian dapat Anda kirimkan ke /conversations/ untuk mengambil riwayat pesan lengkap.
Parameter Kueri
| Parameter | Tipe | Wajib | Deskripsi |
|---|---|---|---|
limit |
integer | Tidak | Jumlah sesi terbaru yang dikembalikan (default: 20, maks: 100) |
website_id |
string | Tidak | Filter sesi berdasarkan ID situs web tertentu |
source |
string | Tidak | Filter berdasarkan sumber sesi: widget, api, whatsapp, instagram, messenger, gorgias, freshchat, zapier |
Respons
{
"success": true,
"sessions": [
{
"session_id": "session_abc123def",
"source": "widget",
"message_count": 5,
"first_message": "What are your business hours?",
"first_message_at": "2024-01-15T10:30:00Z",
"last_message_at": "2024-01-15T10:35:00Z",
"first_response_time_ms": 1840.5,
"first_human_response_at": null,
"started_at": "2024-01-15T10:29:58Z",
"ended_at": "2024-01-15T10:41:12Z",
"taken_over_at": null,
"website_domain": "example.com"
}
]
}
Bidang stempel waktu untuk pelaporan
| Kolom | Deskripsi |
|---|---|
started_at |
Kapan pengunjung membuka obrolan. Hanya tersedia untuk sesi widget, karena sesi yang dibuat melalui API tidak pernah membuka widget. |
first_message_at |
Kapan pesan pertama percakapan disimpan. |
first_response_time_ms |
Berapa lama jawaban pertama berlangsung, dalam milidetik. Gunakan ini untuk waktu respons pertama. |
first_human_response_at |
Kapan salah satu agen Anda mengirim balasan pertama. Nilainya null saat chatbot menangani seluruh percakapan. |
taken_over_at |
Kapan seorang agen mengambil alih obrolan dari chatbot. |
last_message_at |
Kapan pesan terakhir percakapan disimpan. |
ended_at |
Kapan pengunjung meninggalkan obrolan. Obrolan tidak memiliki status selesai atau ditutup, karena pengunjung selalu dapat kembali dan mengajukan pertanyaan lain. |
Semua stempel waktu menggunakan UTC dan format ISO 8601. Anda tidak dapat mengubah zona waktu. Konversikan nilainya di alat pelaporan Anda sendiri.
Contoh (cURL)
curl "https://asyntai.com/api/v1/sessions/?limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"
GET /leads/
Ambil prospek yang dikumpulkan — alamat email dan nomor telepon yang dikirimkan oleh pengunjung selama percakapan chat.
Parameter Kueri
| Parameter | Tipe | Wajib | Deskripsi |
|---|---|---|---|
limit |
integer | Tidak | Jumlah prospek yang dikembalikan (default: 50, maks: 100) |
website_id |
string | Tidak | Filter prospek berdasarkan ID situs web tertentu |
Respons
{
"success": true,
"leads": [
{
"session_id": "session_abc123def",
"email": "[email protected]",
"phone": "+1234567890",
"page_url": "https://example.com/pricing",
"started_at": "2024-01-15T10:30:00Z"
}
]
}
| Kolom | Tipe | Deskripsi |
|---|---|---|
session_id |
string | ID sesi obrolan. Teruskan ke /conversations/ untuk melihat riwayat obrolan lengkap. |
email |
string atau null | Alamat email yang diberikan pengunjung, atau null jika tidak dikumpulkan |
phone |
string atau null | Nomor telepon yang diberikan pengunjung, atau null jika tidak dikumpulkan |
page_url |
string atau null | URL halaman tempat pengunjung mengobrol |
started_at |
string | Stempel waktu ISO 8601 saat sesi obrolan dimulai |
Contoh (cURL)
curl "https://asyntai.com/api/v1/leads/?limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"
Contoh (Python)
import requests
response = requests.get(
"https://asyntai.com/api/v1/leads/",
headers={"Authorization": "Bearer YOUR_API_KEY"},
params={"limit": 20}
)
leads = response.json()["leads"]
for lead in leads:
print(f"{lead['email'] or ''} | {lead['phone'] or ''}")
GET /account/
Dapatkan informasi akun dan statistik penggunaan Anda.
Respons
{
"success": true,
"account": {
"email": "[email protected]",
"plan": "starter",
"messages_used": 150,
"messages_limit": 2500
}
}
Contoh (cURL)
curl https://asyntai.com/api/v1/account/ \
-H "Authorization: Bearer YOUR_API_KEY"
Beberapa situs web? Endpoint basis pengetahuan default ke situs web utama Anda. Jika Anda memiliki beberapa situs web, kirimkan website_id untuk menargetkan yang spesifik. Anda dapat menemukan ID situs web Anda menggunakan GET /websites/.
Batas unggahan harian: Unggahan basis pengetahuan (teks, URL, spreadsheet) tunduk pada batas karakter harian berdasarkan paket Anda. Ini berlaku untuk total konten yang diunggah di semua endpoint basis pengetahuan per hari.
| Paket | Karakter/hari |
|---|---|
| Starter | 300.000 |
| Standard | 1.500.000 |
| Pro | 6.000.000 |
GET /knowledge/
Daftar entri basis pengetahuan Anda. Ini adalah sumber konten yang digunakan chatbot AI Anda untuk menjawab pertanyaan.
Parameter Kueri
| Parameter | Tipe | Wajib | Deskripsi |
|---|---|---|---|
limit |
integer | Tidak | Jumlah entri yang dikembalikan (default: 50, maks: 100) |
website_id |
string | Tidak | Filter berdasarkan ID situs web (default ke situs web utama Anda) |
Respons
{
"success": true,
"entries": [
{
"id": "abc-123-def",
"type": "text",
"title": "Business Hours",
"description": "Manual text content (150 words)",
"created_at": "2024-01-15T10:30:00Z"
},
{
"id": "ghi-456-jkl",
"type": "url",
"title": "About Us - Example",
"description": "Content from https://example.com/about",
"created_at": "2024-01-14T09:00:00Z"
}
]
}
Contoh (cURL)
curl "https://asyntai.com/api/v1/knowledge/?limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"
POST /knowledge/text/
Tambahkan konten teks kustom ke basis pengetahuan Anda. AI akan menggunakan ini untuk menjawab pertanyaan pengunjung.
Isi Permintaan
{
"title": "Return Policy",
"content": "We offer a 30-day return policy on all items. Items must be unused and in original packaging. Refunds are processed within 5-7 business days.",
"website_id": "123"
}
| Parameter | Tipe | Wajib | Deskripsi |
|---|---|---|---|
title |
string | Ya | Judul untuk entri pengetahuan ini |
content |
string | Ya | Konten teks (minimal 10 karakter) |
website_id |
string | Tidak | Situs web target (default ke situs web utama Anda) |
Respons
{
"success": true,
"id": "abc-123-def",
"title": "Return Policy",
"chunks_created": 1
}
Contoh (cURL)
curl -X POST "https://asyntai.com/api/v1/knowledge/text/" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Return Policy", "content": "We offer a 30-day return policy..."}'
POST /knowledge/url/
Tambahkan halaman web ke basis pengetahuan Anda. Konten akan diambil dan diekstrak secara otomatis.
Isi Permintaan
{
"url": "https://example.com/faq",
"website_id": "123"
}
| Parameter | Tipe | Wajib | Deskripsi |
|---|---|---|---|
url |
string | Ya | URL untuk mengambil konten |
website_id |
string | Tidak | Situs web target (default ke situs web utama Anda) |
Respons
{
"success": true,
"id": "abc-123-def",
"title": "FAQ - Example",
"url": "https://example.com/faq",
"chunks_created": 5
}
Contoh (cURL)
curl -X POST "https://asyntai.com/api/v1/knowledge/url/" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/faq"}'
POST /knowledge/spreadsheet/
Unggah spreadsheet CSV atau Excel (.xlsx) ke basis pengetahuan Anda. Setiap baris menjadi entri pengetahuan terpisah, ideal untuk katalog produk, daftar FAQ, tabel harga, dan direktori.
Permintaan
Kirim sebagai multipart/form-data (unggah file), bukan JSON.
| Parameter | Tipe | Wajib | Deskripsi |
|---|---|---|---|
file |
file | Ya | File .csv atau .xlsx. Baris pertama harus berupa header kolom. Maks baris per unggahan: Starter 500, Standard 2.000, Pro 10.000. Baris berlebih akan dipotong. |
website_id |
string | Tidak | Situs web target (default ke situs web utama Anda) |
Respons
{
"success": true,
"id": "abc-123-def",
"title": "products.csv",
"rows_processed": 15,
"chunks_created": 15
}
Contoh (cURL)
curl -X POST "https://asyntai.com/api/v1/knowledge/spreadsheet/" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "[email protected]"
GET /knowledge/{id}/
Baca satu entri basis pengetahuan, termasuk teks yang tersimpan untuknya. Nilai id berasal dari respons GET /knowledge/.
Konten dikembalikan untuk entri yang Anda tambahkan sendiri: teks, berkas, spreadsheet, URL tunggal, dan video. Penelusuran situs web tetap tercantum, tetapi halamannya tidak dikembalikan, karena sumbernya adalah situs publik Anda sendiri. Dalam kasus itu content bernilai null dan bidang reason menjelaskan alasannya.
Respons
{
"success": true,
"id": "abc-123-def",
"type": "text",
"title": "Business Hours",
"description": "Manual text content (150 words)",
"created_at": "2024-01-15T10:30:00Z",
"chunks_count": 3,
"content": "We are open Monday to Friday, 9am to 5pm...",
"content_available": true,
"char_count": 43
}
Contoh (cURL)
curl "https://asyntai.com/api/v1/knowledge/abc-123-def/" \
-H "Authorization: Bearer YOUR_API_KEY"
DELETE /knowledge/{id}/
Hapus entri basis pengetahuan. id dapat ditemukan dari respons GET /knowledge/.
Respons
{
"success": true,
"message": "Knowledge base entry deleted"
}
Contoh (cURL)
curl -X DELETE "https://asyntai.com/api/v1/knowledge/abc-123-def/" \
-H "Authorization: Bearer YOUR_API_KEY"
Tip: Anda juga dapat mengelola webhook dari Pengaturan API halaman tanpa menulis kode apa pun.
GET /webhooks/
Daftar webhook terdaftar Anda.
Respons
{
"success": true,
"webhooks": [
{
"id": "abc-123-def",
"url": "https://example.com/webhook",
"events": ["message.received", "escalation.requested"],
"is_active": true,
"created_at": "2024-01-15T10:30:00Z"
}
]
}
Contoh (cURL)
curl "https://asyntai.com/api/v1/webhooks/" \
-H "Authorization: Bearer YOUR_API_KEY"
POST /webhooks/
Daftarkan webhook baru untuk menerima notifikasi event secara real-time.
Event yang Tersedia
| Event | Deskripsi |
|---|---|
message.received |
Pengunjung mengirim pesan dan menerima respons |
conversation.started |
Sesi chat baru telah dimulai |
escalation.requested |
AI memicu eskalasi ke agen manusia |
takeover.started |
Agen manusia mengambil alih sesi chat |
Isi Permintaan
{
"url": "https://example.com/webhook",
"events": ["message.received", "escalation.requested"],
"website_id": "123"
}
| Parameter | Tipe | Wajib | Deskripsi |
|---|---|---|---|
url |
string | Ya | URL HTTPS untuk menerima permintaan POST webhook |
events |
array | Ya | Daftar event untuk berlangganan (lihat tabel di atas) |
website_id |
string | Tidak | Situs web target (default ke situs web utama Anda) |
Respons
{
"success": true,
"webhook": {
"id": "abc-123-def",
"url": "https://example.com/webhook",
"events": ["message.received", "escalation.requested"],
"secret": "whsec_abc123...",
"created_at": "2024-01-15T10:30:00Z"
}
}
Memverifikasi webhook: Setiap webhook menyertakan secret (ditampilkan hanya saat pembuatan). Setiap POST ke URL Anda menyertakan X-Webhook-Signature header — HMAC-SHA256 dari badan permintaan yang ditandatangani dengan kunci rahasia Anda.
Contoh (cURL)
curl -X POST "https://asyntai.com/api/v1/webhooks/" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/webhook", "events": ["message.received"]}'
DELETE /webhooks/{id}/
Hapus webhook. id dapat ditemukan dari respons GET /webhooks/.
Respons
{
"success": true,
"message": "Webhook deleted"
}
Contoh (cURL)
curl -X DELETE "https://asyntai.com/api/v1/webhooks/abc-123-def/" \
-H "Authorization: Bearer YOUR_API_KEY"
Respons Error
Semua respons error mengikuti format ini:
{
"success": false,
"error": "Error message describing what went wrong"
}
| Kode Status | Deskripsi |
|---|---|
400 |
Permintaan Buruk - Parameter tidak valid atau kolom wajib hilang |
401 |
Tidak Terotorisasi - Kunci API tidak valid atau hilang |
429 |
Terlalu Banyak Permintaan - Batas pesan tercapai untuk paket Anda |
503 |
Layanan Tidak Tersedia - Layanan AI sementara tidak tersedia |
Batas Laju
Penggunaan API dibatasi oleh paket langganan Anda:
- Free: 100 pesan/bulan
- Starter ($39/bln): 2.500 pesan/bulan
- Standard ($139/bln): 15.000 pesan/bulan
- Pro ($449/bln): 50.000 pesan/bulan
Butuh Bantuan?
Jika Anda memiliki pertanyaan atau mengalami masalah, hubungi kami di [email protected].