Gateway API Documentation
Kling v3 Motion ControlServer to ServerWhite Label
Base URL: https://dmsai.extremeaffiliate.web.id
Billing: per second | Max durasi: 30 detik
Portal user: /portal/login
Quick Start
1
Topup Saldo
Login ke portal, transfer ke rekening admin, lalu konfirmasi admin.
/portal/login
2
Cek Saldo
Cek saldo sebelum generate.
GET /v1/balance
3
Create Job
Kirim job motion control via backend server.
POST /v1/motion/generate
4
Polling Result
Ambil status job sampai selesai.
GET /v1/motion/:jobId
Token akses hanya disimpan di backend server, bukan di frontend/browser.
Autentikasi
Gunakan salah satu header berikut untuk endpoint /v1/*.
x-access-token: <ACCESS_TOKEN> atau Authorization: Bearer <ACCESS_TOKEN>
Endpoint Utama
| Method | Path | Keterangan |
|---|---|---|
| GET | /v1/pricing | Harga aktif dan konfigurasi billing per detik. |
| GET | /v1/balance | Saldo user dan estimasi sisa generate. |
| GET | /v1/transactions | Riwayat saldo debit/kredit. |
| POST | /v1/motion/generate | Buat job motion control. Opsi mode: std atau pro. |
| GET | /v1/motion/:jobId | Cek status job. |
| GET | /v1/media/:mediaId | Detail file hasil. |
Topup transfer manual dilakukan via portal: /portal/login.
Contoh Request
Pricing
curl -X GET 'https://dmsai.extremeaffiliate.web.id/v1/pricing' \ -H 'x-access-token: ACCESS_TOKEN'
Generate Video
curl -X POST 'https://dmsai.extremeaffiliate.web.id/v1/motion/generate' \
-H 'Content-Type: application/json' \
-H 'x-access-token: ACCESS_TOKEN' \
-d '{
"imageUrl": "https://.../image.jpg",
"referenceVideoUrl": "https://.../ref.mp4",
"mode": "pro",
"prompt": "",
"durationSec": 30
}'
Charge formula: ceil(durationSec * RATE_BY_MODE), dengan mode=std|pro.
Backend Proxy (Node.js)
import express from "express";
import fetch from "node-fetch";
const app = express();
app.use(express.json());
const GATEWAY_BASE = "https://dmsai.extremeaffiliate.web.id";
const ACCESS_TOKEN = process.env.GATEWAY_TOKEN;
app.post("/api/motion/generate", async (req, res) => {
try {
const r = await fetch(GATEWAY_BASE + "/v1/motion/generate", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-access-token": ACCESS_TOKEN
},
body: JSON.stringify(req.body)
});
const data = await r.json();
res.status(r.status).json(data);
} catch (err) {
res.status(500).json({ ok: false, error: { message: "gateway unreachable" } });
}
});
app.get("/api/motion/:jobId", async (req, res) => {
const r = await fetch(GATEWAY_BASE + "/v1/motion/" + encodeURIComponent(req.params.jobId), {
headers: { "x-access-token": ACCESS_TOKEN }
});
const data = await r.json();
res.status(r.status).json(data);
});
app.get("/api/balance", async (_req, res) => {
const r = await fetch(GATEWAY_BASE + "/v1/balance", {
headers: { "x-access-token": ACCESS_TOKEN }
});
const data = await r.json();
res.status(r.status).json(data);
});
app.listen(3000);
Error Code
| HTTP | Kode | Keterangan |
|---|---|---|
| 401 | missing_client_key / invalid_client_key | Token akses tidak ada atau tidak valid. |
| 402 | insufficient_balance | Saldo tidak cukup untuk generate. |
| 429 | rate_limited | Terlalu banyak request. |
| 5xx | upstream_error / lainnya | Gangguan sementara, lakukan retry bertahap. |