Lompat ke konten utama
Dokumentasi AdForm
llms.txt Pusat Bantuan

API Produk

Referensi lengkap dua operasi produk yang bisa dipanggil dengan API key AdForm — ambil snippet embed dan duplikat produk, beserta parameter, contoh, dan daftar error.

products:readproducts:write

/api/products.php

Endpoint /api/products.php melayani dua operasi programatik yang bisa dipanggil dengan API key. Operasi dipilih lewat query parameter action.

OperasiMethodURLScope
Ambil snippet embedGET/api/products.php?action=embed&id={id}products:read
Duplikat produkPOST/api/products.php?action=duplicate&id={id}products:write

action wajib. Tanpa action, request masuk ke jalur dashboard yang butuh sesi login, bukan API key — API key Anda akan diabaikan di jalur itu. action yang tidak dikenal dibalas 400:

{ "error": "Unknown action: list" }

Semua harga adalah integer rupiah tanpa desimal (150000 = Rp150.000).


#Ambil snippet embed produk

GET /api/products.php?action=embed&id={id}
X-API-Key: adk_...

Scope: products:read.

Mengembalikan harga, varian, dan potongan HTML siap tempel untuk satu produk. Ini cara yang benar untuk mendapatkan URL form dan snippet iframe — jangan merangkainya sendiri, karena bentuk URL bergantung pada tenant_id dan slug produk.

#Parameter

NamaLetakTipeWajibKeterangan
actionquerystringHarus embed.
idqueryintegerID produk. Harus > 0.

#Contoh request

curl -sS \
  -H "X-API-Key: adk_0123456789abcdef0123456789abcdef0123456789abcdef" \
  "https://adform.id/api/products.php?action=embed&id=12"

#Contoh response — 200 OK

{
  "success": true,
  "id": 12,
  "name": "Kaos Polos Hitam",
  "slug": "kaos-polos-hitam",
  "price": 89000,
  "sale_price": 69000,
  "variants": [
    { "dimension": "Ukuran", "options": ["M", "L", "XL"] }
  ],
  "variant_prices": [69000, 69000, 79000],
  "variant_display": "small",
  "embed": {
    "product_id": 12,
    "tenant_id": 34,
    "slug": "kaos-polos-hitam",
    "form_url": "https://adform.id/t/34/kaos-polos-hitam",
    "iframe": "<iframe src=\"https://adform.id/t/34/kaos-polos-hitam\"\n  style=\"width:100%;min-height:700px;border:none;\"\n  loading=\"eager\" scrolling=\"no\" frameborder=\"0\"></iframe>",
    "iframe_with_pixel": "<iframe src=\"https://adform.id/t/34/kaos-polos-hitam\"\n  style=\"width:100%;min-height:700px;border:none;\"\n  loading=\"eager\" scrolling=\"no\" frameborder=\"0\"></iframe>\n<script src=\"https://adform.id/embed.js\"></script>"
  }
}

#Field response

FieldTipeKeterangan
successbooleanSelalu true pada response sukses.
idintegerID produk.
namestringNama produk.
slugstringSlug produk, dipakai di URL form.
priceintegerHarga dasar (rupiah).
sale_priceinteger | nullHarga coret/promo. null kalau tidak dipakai.
variantsarrayDaftar variasi. Lihat di bawah.
variant_pricesarrayHarga per kombinasi varian. Bentuknya mengikuti variants.
variant_displaystringGaya tampilan pilihan varian di form, mis. "small".
embed.product_idintegerSama dengan id.
embed.tenant_idintegerID tenant pemilik key.
embed.slugstringSama dengan slug.
embed.form_urlstringURL form order produk ini.
embed.iframestringHTML iframe siap tempel.
embed.iframe_with_pixelstringSama seperti iframe, plus <script src=".../embed.js"> untuk auto-resize, penerusan parameter iklan, dan tracking pixel. Ini yang sebaiknya Anda pakai.

#Bentuk variants dan variant_prices

Produk tanpa varian: variants berupa array kosong dan variant_prices kosong. Harga diambil dari price / sale_price.

Produk dengan satu variasi:

{
  "variants": [{ "dimension": "Ukuran", "options": ["M", "L", "XL"] }],
  "variant_prices": [69000, 69000, 79000]
}

variant_prices adalah daftar angka datar, indeksnya sejajar dengan options.

Produk dengan dua variasi (matriks Variasi 1 × Variasi 2):

{
  "variants": [
    { "dimension": "Warna", "options": ["Hitam", "Putih"] },
    { "dimension": "Ukuran", "options": ["M", "L", "XL"] }
  ],
  "variant_prices": [
    [69000, 69000, 79000],
    [72000, 72000, 82000]
  ]
}

Baris = opsi variasi pertama, kolom = opsi variasi kedua. Jadi Putih/XL = variant_prices[1][2] = 82000.

Produk lama bisa memakai format varian datar tanpa field dimension. Perlakukan keberadaan dimension sebagai penanda format, seperti yang dilakukan form AdForm sendiri.


#Duplikat produk

POST /api/products.php?action=duplicate&id={id}
X-API-Key: adk_...
Content-Type: application/json

Scope: products:write.

Menyalin produk yang sudah ada menjadi produk baru di tenant yang sama, dengan nama baru dan (opsional) harga/varian/gambar yang di-override. Response langsung berisi embed, jadi satu panggilan sudah cukup untuk mendapat produk baru plus snippet siap pasang.

Kirim sebagai POST dengan body JSON — parameter override dibaca dari body, jadi request tanpa body tidak akan berhasil.

#Parameter query

NamaTipeWajibKeterangan
actionstringHarus duplicate.
idintegerID produk sumber yang akan disalin.

#Parameter body (JSON)

NamaTipeWajibDefaultKeterangan
namestringNama produk baru. Tidak boleh kosong.
slugstringditurunkan dari nameSlug produk baru. Kalau kosong, dibuat dari name (huruf kecil, karakter non-alfanumerik jadi -). Kalau slug sudah dipakai, sistem menambahkan -2, -3, dst.
image_urlstringikut sumberGanti gambar utama produk baru.
price_modestringikut sumber"satuan" atau "varian". Menentukan bagaimana harga produk baru dibentuk. Kalau tidak dikirim, seluruh struktur harga disalin apa adanya dari sumber.
priceintegerikut sumberHarga dasar. Nilai negatif dijadikan 0. Dipakai pada price_mode: "satuan", dan sebagai harga dasar pada mode "varian".
sale_priceinteger | nullikut sumberHarga coret. Kirim null untuk menghapus. Hanya pada price_mode: "satuan".
variantsarrayikut sumberStruktur variasi produk baru. Hanya dipakai pada price_mode: "varian".
variant_pricesarrayikut sumberHarga per kombinasi varian. Bentuknya wajib cocok dengan variants (lihat validasi di bawah).
variant_compare_pricesarrayikut sumberHarga coret per kombinasi varian. Bentuk sama dengan variant_prices; nilai 0 berarti tanpa coret.
variant_displaystringikut sumberGaya tampilan pilihan varian, mis. "small".

Pada price_mode: "satuan", varian produk baru dikosongkan — produk hasilnya jadi produk harga tunggal meskipun sumbernya bervarian.

#Yang ikut tersalin

Selain nama dan slug, produk baru mewarisi konfigurasi produk sumber: deskripsi, berat, metode pembayaran dan channel e-payment, setelan COD, distribusi CS, setelan checkout, order bump, template follow-up, template redirect pelanggan, ID Meta Pixel dan GTM, label form, form_fields, tipe produk (termasuk produk digital), serta penugasan tim (product_team) dari produk sumber.

Status produk baru mengikuti status produk sumber. Kalau sumbernya aktif, hasil duplikat langsung aktif dan formnya bisa diakses publik. Kalau Anda ingin menyiapkan dulu, duplikat dari produk sumber yang nonaktif.

#Contoh — duplikat sederhana

curl -sS -X POST \
  -H "X-API-Key: adk_0123456789abcdef0123456789abcdef0123456789abcdef" \
  -H "Content-Type: application/json" \
  -d '{"name":"Kaos Polos Hitam - Promo Juli"}' \
  "https://adform.id/api/products.php?action=duplicate&id=12"

#Contoh — jadikan produk harga tunggal

{
  "name": "Kaos Polos Hitam - Edisi Promo",
  "slug": "kaos-hitam-promo",
  "price_mode": "satuan",
  "price": 79000,
  "sale_price": 59000
}

#Contoh — ganti struktur varian

{
  "name": "Kaos Polos - Katalog Baru",
  "price_mode": "varian",
  "price": 69000,
  "variants": [
    { "dimension": "Warna", "options": ["Hitam", "Putih"] },
    { "dimension": "Ukuran", "options": ["M", "L"] }
  ],
  "variant_prices": [
    [69000, 74000],
    [69000, 74000]
  ],
  "variant_compare_prices": [
    [89000, 94000],
    [89000, 94000]
  ],
  "variant_display": "small"
}

#Contoh response — 201 Created

{
  "success": true,
  "id": 87,
  "slug": "kaos-polos-hitam-promo-juli",
  "source_id": 12,
  "embed": {
    "product_id": 87,
    "tenant_id": 34,
    "slug": "kaos-polos-hitam-promo-juli",
    "form_url": "https://adform.id/t/34/kaos-polos-hitam-promo-juli",
    "iframe": "<iframe src=\"https://adform.id/t/34/kaos-polos-hitam-promo-juli\"\n  style=\"width:100%;min-height:700px;border:none;\"\n  loading=\"eager\" scrolling=\"no\" frameborder=\"0\"></iframe>",
    "iframe_with_pixel": "<iframe src=\"https://adform.id/t/34/kaos-polos-hitam-promo-juli\"\n  style=\"width:100%;min-height:700px;border:none;\"\n  loading=\"eager\" scrolling=\"no\" frameborder=\"0\"></iframe>\n<script src=\"https://adform.id/embed.js\"></script>"
  }
}

Perhatikan slug di response — belum tentu sama dengan yang Anda kirim, karena bisa ditambah akhiran angka bila bentrok. Selalu pakai slug dan embed.form_url dari response, jangan menebak.

#Validasi harga varian

Bentuk variant_prices diperiksa sebelum disimpan supaya form tidak pernah menagih harga yang salah:

  • Satu variasi → variant_prices harus daftar angka datar, bukan bersarang.
  • Dua atau tiga variasi → variant_prices harus matriks bersarang yang dimensinya persis sama dengan jumlah opsi tiap variasi, dan setiap sel harus diisi angka lebih dari 0.
  • variant_compare_prices, kalau dikirim dan tidak kosong, harus berbentuk sama. Nilai 0 diperbolehkan (artinya tanpa harga coret).
  • Setiap variasi minimal punya satu opsi.

Kalau tidak lolos, request dibalas 400 dengan pesan yang menyebutkan masalahnya, misalnya:

{ "error": "variant_prices tiap kombinasi wajib diisi harga lebih dari 0 (ada sel kosong/0)." }

atau

{ "error": "variant_prices bentuk matriks tidak sesuai jumlah opsi variasi." }

#Daftar error

StatusBodyOperasiPenyebab
400{"error":"id required"}keduanyaid tidak dikirim atau ≤ 0.
400{"error":"name required"}duplicateBody tidak berisi name, atau name kosong.
400{"error":"cannot derive slug from name"}duplicatename tidak mengandung karakter yang bisa dijadikan slug (mis. hanya simbol). Kirim slug sendiri.
400{"error":"Unknown action: ..."}Nilai action bukan embed atau duplicate.
400pesan validasi varianduplicateLihat bagian validasi harga varian di atas.
401{"error":"API key required (X-API-Key header)"}keduanyaHeader tidak dikirim.
401{"error":"Malformed API key"}keduanyaBentuk key salah.
401{"error":"Invalid API key"}keduanyaKey tidak dikenal.
401{"error":"API key revoked"}keduanyaKey sudah dicabut.
401{"error":"API key expired"}keduanyaKey sudah kedaluwarsa.
403{"error":"Tenant inactive"}keduanyaTenant pemilik key nonaktif.
403{"error":"Missing scope: products:read"}embedKey tidak punya scope products:read.
403{"error":"Missing scope: products:write"}duplicateKey tidak punya scope products:write.
404{"error":"Product not found"}embedProduk dengan id tersebut tidak ada di tenant ini.
404{"error":"Source product not found"}duplicateProduk sumber tidak ada di tenant ini.
429{"error":"Terlalu banyak permintaan. Coba lagi nanti."}keduanyaRate limit 60 request/menit per IP terlampaui. Lihat header Retry-After.

#Yang tidak tersedia di endpoint ini

Supaya tidak ada waktu terbuang: dengan API key, /api/products.php hanya melayani action=embed dan action=duplicate. Tidak ada list produk, ambil detail lengkap, buat produk dari nol, ubah, atau hapus lewat API key. Operasi itu ada di dashboard dan butuh sesi login dashboard.

Kalau Anda butuh salah satunya untuk integrasi, kabari kami lewat Pusat Bantuan — permintaan konkret dari integrator yang menentukan urutan pengerjaan.