# Pemecahan masalah

> Solusi untuk error CORS, ketidakcocokan origin, challenge_required, 429, field yang tidak dikenal, dan error kuota.

Mulailah dari respons. Setiap jawaban dari Ikiform punya header `X-Request-Id` dan, untuk error, `error.code` yang stabil. Perintah curl ini menampilkan keduanya, dari origin yang sama dengan yang akan dikirim situs Anda:

`Terminal`:

```bash
curl -i https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Origin: https://example.com" \
  -d '{"email":"ada@example.com"}'
```

Melihat error `5xx` atau timeout dari Ikiform sendiri? Periksa [status.ikiform.com](https://status.ikiform.com) untuk insiden yang sedang terjadi terlebih dahulu.

## Browser menyatakan CORS memblokir request

Endpoint kiriman mengizinkan semua origin, jadi kegagalan CORS yang sungguhan biasanya berarti request tidak pernah sampai ke Ikiform, atau dikirim ke URL yang salah.

- Pastikan URL-nya `https://ikiform.com/f/<formId>` dengan ID `frm_` lengkap, misalnya `frm_xxxxxxxxxxxxxxxx`, dan tanpa path tambahan di belakangnya.
- Anda memanggil `/api/v1` dari browser. REST API sengaja menolak browser; panggil dari server Anda.
- Ad blocker, ekstensi privasi, atau proxy perusahaan memblokir request. Coba jendela privat tanpa ekstensi.
- `Content-Security-Policy` milik situs Anda sendiri memblokirnya. Tambahkan `https://ikiform.com` ke `connect-src`, dan ke `form-action` untuk kiriman HTML biasa.

Periksa preflight secara langsung; seharusnya menjawab `204` dengan origin Anda dipantulkan kembali:

`Terminal`:

```bash
curl -i -X OPTIONS https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx \
  -H "Origin: https://example.com" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: content-type"
```

## Kiriman masuk ke spam dengan origin_mismatch

Formulir punya domain yang diizinkan dan kiriman berasal dari tempat lain. Dashboard menampilkan `origin_mismatch` di antara alasan spam.

- Tambahkan setiap domain tempat formulir disajikan, termasuk `www`, staging, dan domain pratinjau. Subdomain dari domain yang tercantum sudah otomatis cocok.
- Tambahkan `localhost` selama pengembangan lokal.
- Kiriman dari server Anda sendiri tidak membawa `Origin`. Kirim secret key, yang melewati pemeriksaan ini.
- Jika **Reject** dipilih alih-alih **Mark as spam**, kiriman yang sama mendapat `403 origin_not_allowed`.

## 403 challenge_required

Pemeriksaan spam formulir diatur ke **Ikiform** dan kiriman tidak punya token Turnstile.

1. Kode browser: panggil `challenge(formId)` dari SDK tepat sebelum setiap kiriman, dan berikan tokennya ke `submit` sebagai `turnstileToken`.
2. Kode server: kirim `Authorization: Bearer ik_sk_...` dengan secret key; secret key melewati pemeriksaan ini.
3. Kiriman HTML biasa tidak pernah melihat kode ini; mereka mendapat halaman pemeriksaan. Jika Anda melihatnya dari kiriman formulir, ada sesuatu yang mengirim `Accept: application/json`.
4. Menguji dengan curl? Matikan pemeriksaan untuk formulir tes, atau gunakan secret key.

`403 captcha_failed` berarti token dikirim tetapi gagal diverifikasi. Token hanya sekali pakai dan kedaluwarsa setelah 300 detik, jadi ambil token baru untuk setiap percobaan.

## 429 rate_limited

- Baca `Retry-After` dan tunggu selama jumlah detik itu.
- Menguji secara manual? Preset Standard mengizinkan 5 kiriman per menit dari satu IP, dan 3 dalam 10 detik. Ubah formulir tes ke Relaxed.
- Mengirim dari server Anda untuk setiap pengunjung? Semua kiriman berbagi IP server Anda. Kirim dari browser, atau pilih Relaxed atau Custom.
- Banyak orang di balik satu jaringan kantor atau acara juga berbagi IP. Relaxed mengizinkan 20 per menit.

## 422 dengan Unknown field

Formulir punya field yang didefinisikan dan kiriman mengirim nama yang tidak ada di definisi. `error.fields` menyebutnya, misalnya `{ "website": ["Unknown field \"website\""] }`.

- Tambahkan field ke definisi, atau hapus input-nya.
- Ganti nama input agar diawali `_` jika hanya penanda untuk Anda; nama reserved dibuang, bukan divalidasi.
- Pastikan nama honeypot sesuai dengan pengaturan **Honeypot field** formulir.
- ID field ditulis dalam snake_case huruf kecil: `firstName` di markup Anda tidak sama dengan `first_name` di definisi.

## 429 quota_exceeded

Workspace menerima 2 kali batas bulanannya bulan ini dan berhenti menerima kiriman sampai bulan berikutnya dimulai atau workspace upgrade. Lihat [Pemakaian bulanan](https://ikiform.com/id/docs/limits.md#monthly-usage).

## Kiriman tidak muncul

- Cari di filter spam. Spam mendapat respons sukses biasa, jadi pengunjung tidak bisa membedakannya.
- Pastikan formulir tidak dijeda, dan ID di `action` Anda sesuai dengan dashboard.
- Kiriman browser yang menampilkan halaman error Ikiform berarti ditolak; halaman itu mencantumkan alasannya.

## Webhook gagal

- `no_matching_signature`: verifikasi terhadap body mentah, sebelum JSON diurai, dan pastikan Anda menyalin secret `whsec_` yang benar. Tempel sebuah pengiriman ke [verifikator](https://ikiform.com/id/docs/webhooks.md#verifier).
- `timestamp_too_old`: jam server Anda tidak tepat, atau Anda mengirim ulang pengiriman lama.
- Timeout: jawab dalam 15 detik dan kerjakan pekerjaan yang lambat setelahnya.
- Redirect tidak diikuti. Gunakan URL final, termasuk garis miring di akhir yang diharapkan framework Anda.
- Endpoint dinonaktifkan setelah 5 hari gagal atau karena `410`. Perbaiki, lalu aktifkan kembali dari halaman endpoint.
