JavaScript dan fetch
Endpoint kiriman secara rinci: format body, header, CORS, respons, dan idempotensi.
Kode apa pun yang bisa mengirim request HTTP bisa mengirim ke Ikiform. Kirim JSON, FormData, atau data urlencoded ke https://ikiform.com/f/<formId> dan baca jawaban JSON-nya. SDK membungkus ini dalam satu fungsi, tetapi sifatnya opsional. Untuk penyiapan langkah demi langkah di stack tertentu, lihat Panduan per platform.
Dengan fetch
const response = await fetch("https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx", {
method: "POST",
headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify({
name: "Ada Lovelace",
email: "ada@example.com",
message: "Hello",
}),
});
const result = await response.json();
if (!result.ok) console.error(result.error.code, result.error.fields);Coba sekarang
curl https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx \
-H "Content-Type: application/json" \
-d '{"name":"Ada Lovelace","email":"ada@example.com","message":"Hello from the Ikiform docs."}'Masukkan ID formulir Anda sendiri untuk mengirim ini sebagai request sungguhan.
Endpoint
| Metode | Path | Fungsinya |
|---|---|---|
POST | /f/<formId> | Membuat kiriman |
OPTIONS | /f/<formId> | Preflight CORS, selalu 204 |
GET | /f/<formId>/schema | Definisi field publik formulir, lihat shadcn/ui |
GET | /f/<formId>/thanks | Halaman terima kasih hosted |
GET | /f/<formId>/challenge | Frame pemeriksaan manusia Ikiform, dipakai oleh SDK |
Membuka /f/<formId> langsung di tab browser adalah GET, yang dijawab 404 not_found. Itu memang seharusnya: endpoint ini hanya menerima kiriman.
Format body
| Content-Type | Bentuk | Catatan |
|---|---|---|
application/json dan tipe +json | Satu objek JSON | Nilai bisa berupa string, angka, boolean, array, dan objek, bertingkat maksimal 3 level termasuk objek teratas |
application/x-www-form-urlencoded | Pasangan nama dan nilai | Nama yang berulang dan name[] menjadi array |
multipart/form-data | Pasangan nama dan nilai | Sama seperti urlencoded; file sungguhan ditolak |
| Selain itu | 415 unsupported_media_type |
Body harus UTF-8. charset selain utf-8 mendapat 415 unsupported_charset, dan byte yang bukan UTF-8 valid mendapat kode yang sama. Array JSON atau body yang rusak mendapat 400 invalid_body.
Header
Header request
| Header | Wajib | Efek |
|---|---|---|
Content-Type | Ya | Menentukan parser body, lihat di atas |
Accept | Tidak | application/json memaksa jawaban JSON, lihat JSON atau redirect |
Idempotency-Key | Tidak | Membuat percobaan ulang aman, hingga 255 karakter, lihat Idempotensi |
Authorization | Tidak | Bearer ik_sk_... atau Bearer ik_pub_..., lihat Dari server |
Origin, Referer | Dikirim oleh browser | Dicocokkan dengan domain yang diizinkan formulir |
Header respons
| Header | Kapan | Nilai |
|---|---|---|
X-Request-Id | Setiap respons | req_..., diulang sebagai request_id di body error |
Retry-After | 429 | Detik sampai kiriman berikutnya diizinkan |
Location | Sukses browser 303 | Redirect Anda atau halaman terima kasih hosted |
Access-Control-Allow-Origin | Saat request punya Origin | Origin milik request itu sendiri |
Access-Control-Expose-Headers | Dengan CORS | X-Request-Id, Retry-After, agar kode browser bisa membaca keduanya |
Cache-Control | Sukses | no-store |
CORS
Endpoint kiriman menerima kiriman lintas origin dari situs mana pun. Preflight selalu berhasil dan memantulkan origin request. Tidak ada cookie atau kredensial yang dipakai, jadi bukan CORS yang melindungi formulir Anda, melainkan domain yang diizinkan. Jika domain yang diizinkan diatur, kiriman dari situs lain disimpan sebagai spam atau ditolak, tergantung pengaturan formulir. Lihat Domain yang diizinkan.
OPTIONS /f/frm_xxxxxxxxxxxxxxxx HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Accept, Idempotency-Key, Authorization
Access-Control-Max-Age: 86400
Vary: Origin/api/v1 berbeda: API ini tidak mengirim header CORS dan menjawab preflight browser dengan 405, jadi secret key tidak pernah bisa dipakai dari halaman web.Respons
Sukses berupa 201 dengan ID kiriman baru. Error memakai satu format envelope di mana pun, dengan error field yang diberi key berdasarkan ID field saat validasi gagal. Setiap kode tercantum di Error.
{ "ok": true, "id": "sub_01k7v2c9t3e8m5q4x6z0a1b2c3" }201. Spam disimpan terpisah dan tidak pernah sampai ke webhook atau inbox Anda.Idempotensi
Kirim header Idempotency-Key, atau field _idempotency, agar percobaan ulang aman. Key bisa hingga 255 karakter dan berlaku untuk formulir tersebut selama 24 jam. Header yang dipakai jika keduanya dikirim.
| Coba ulang dengan | Hasil |
|---|---|
| Key yang sama dan field yang sama | Respons pertama dikembalikan lagi. Tidak ada kiriman kedua yang dibuat. |
| Key yang sama dan field yang berbeda | 422 idempotency_mismatch |
| Key yang sama saat request pertama masih berjalan | 409 idempotency_in_progress |
Kiriman yang gagal sebelum disimpan, seperti error validasi, tidak menyimpan key-nya, jadi Anda bisa memperbaiki data dan mencoba ulang dengan key yang sama. Loop percobaan ulang yang aman:
const key = crypto.randomUUID();
async function send(attempt = 1) {
const response = await fetch("https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx", {
method: "POST",
headers: { "Content-Type": "application/json", "Idempotency-Key": key },
body: JSON.stringify({ email: "ada@example.com" }),
}).catch(() => null);
if (response && response.status < 500 && response.status !== 429) return response.json();
if (attempt === 3) throw new Error("Ikiform is unreachable");
const wait = Number(response?.headers.get("Retry-After")) || attempt * 2;
await new Promise((resolve) => setTimeout(resolve, wait * 1000));
return send(attempt + 1);
}Panduan per platform
Framework
- Next.jsClient component, atau server action.
- ReactState pending, error, dan sukses.
- VueSingle-file component.
- NuxtMengirim sebelum hidrasi dan dengan
$fetchsetelahnya. - SvelteKomponen Svelte 5 dan server action.
- SvelteKitHalaman prerender dengan progressive enhancement.
- AstroFormulir tanpa JavaScript, dengan peningkatan opsional.
- GatsbyFormulir statis, atau Gatsby Function.
- JavaScript biasa
fetchdengan error inline.
Static site generator
- HugoPartial dan shortcode untuk file konten.
- JekyllInclude, dan penyiapan GitHub Pages.
- EleventyShortcode untuk Nunjucks, Liquid, dan Markdown.