Ikhtisar
API Publik Formict memungkinkan Anda mengintegrasikan sistem yang sudah ada — ERP, CRM, platform dispatching, atau alur kerja kustom — dengan Formict. Anda dapat membuat dan mengelola tugas, pelanggan, kendaraan, lokasi, dan shift secara programatis.
Persyaratan
- Paket: Pro atau Enterprise (akses API tidak tersedia pada paket Free atau Starter)
- API Key: Buat dari Settings → API Keys di dashboard Formict
Playground interaktif
Playground API interaktif langsung tersedia di api.formict.com/v1/public/docs. Anda dapat menelusuri endpoint, mengisi parameter, menempelkan API key Anda, dan mengirim request nyata langsung dari browser.
Autentikasi
Semua request API harus menyertakan API key Anda di header Authorization
menggunakan skema Bearer:
Authorization: Bearer fmct_live_xxxxxxxxxxxxxxxxxxxxxxxx Format API key
API key mengikuti format fmct_live_ diikuti oleh string acak.
Prefiks fmct_live_ adalah pengenal publik yang terlihat di dashboard.
Key lengkap hanya ditampilkan sekali saat pembuatan — simpan dengan aman.
Scope
Setiap API key dibuat dengan satu atau lebih scope yang menentukan apa yang bisa dilakukan:
| Scope | Izin |
|---|---|
read | Membaca resource (request GET) |
write | Membuat dan memperbarui resource (request POST, PATCH, DELETE) |
admin | Akses penuh termasuk tim dan pengaturan |
Request akan gagal dengan 403 Forbidden jika API key tidak memiliki scope yang diperlukan.
Praktik keamanan terbaik
- Jangan pernah mengekspos API key di kode sisi klien atau repositori publik
- Gunakan scope minimum yang diperlukan untuk setiap integrasi
- Tetapkan tanggal kedaluwarsa untuk key yang tidak memerlukan akses permanen
- Buat ulang key segera jika Anda menduga key telah disusupi
- Gunakan key terpisah untuk integrasi yang berbeda untuk mengisolasi akses
Format Request
Base URL
https://api.formict.com/v1/public Tipe konten
Semua body request harus berformat JSON dengan header Content-Type:
Content-Type: application/json Contoh request
curl -X GET "https://api.formict.com/v1/public/jobs?page=1&limit=20" \
-H "Authorization: Bearer fmct_live_xxxxxxxx" \
-H "Content-Type: application/json" Format Response
Semua response berformat JSON. Response yang berhasil membungkus data dalam envelope data:
{
"data": {
"jobs": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"totalPages": 3
}
},
"message": "Success"
} Response resource tunggal mengikuti pola yang sama:
{
"data": {
"job": {
"id": "clx1234...",
"title": "AC Maintenance",
"status": "CREATED",
...
}
},
"message": "Success"
} Kode status HTTP
| Status | Arti |
|---|---|
200 | Berhasil |
201 | Resource berhasil dibuat |
400 | Request tidak valid (error validasi) |
401 | Tidak terotorisasi (API key tidak ada atau tidak valid) |
403 | Terlarang (scope tidak mencukupi) |
404 | Resource tidak ditemukan |
422 | Entitas tidak dapat diproses (error logika bisnis) |
429 | Batas rate terlampaui |
500 | Error server internal |
Penanganan Error
Response error menyertakan field error dengan pesan yang mudah dibaca manusia
dan opsional code yang dapat dibaca mesin:
{
"error": "Job not found",
"code": "NOT_FOUND"
} Kode error umum
| Kode | Deskripsi |
|---|---|
NOT_FOUND | Resource yang diminta tidak ada atau telah dihapus |
VALIDATION_ERROR | Body request gagal validasi (field hilang atau tidak valid) |
TERMINAL_STATE | Tidak dapat mengubah tugas dengan status COMPLETED atau CANCELLED |
JOB_IN_PROGRESS | Tidak dapat menghapus tugas yang sedang berlangsung |
FORBIDDEN | API key tidak memiliki scope yang diperlukan untuk operasi ini |
RATE_LIMITED | Terlalu banyak request — tunggu dan coba lagi |
Paginasi
Endpoint daftar mendukung paginasi berbasis kursor dengan parameter query page dan limit:
| Parameter | Tipe | Default | Deskripsi |
|---|---|---|---|
page | number | 1 | Nomor halaman (dimulai dari 1) |
limit | number | 20 | Item per halaman (maks 100) |
Response menyertakan objek pagination:
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"totalPages": 3
} Batas Rate
API key memiliki batas rate yang dapat dikonfigurasi yang ditetapkan saat pembuatan (request per menit).
Ketika Anda melampaui batas rate, API mengembalikan 429 Too Many Requests.
Response menyertakan header yang menunjukkan status batas rate Anda saat ini:
| Header | Deskripsi |
|---|---|
X-RateLimit-Limit | Maksimum request per menit |
X-RateLimit-Remaining | Sisa request dalam jendela waktu saat ini |
X-RateLimit-Reset | Detik hingga batas rate direset |
Tugas
Tugas adalah item pekerjaan layanan lapangan — pengiriman, panggilan pemeliharaan, inspeksi, atau tugas apa pun yang dilakukan di lokasi pelanggan.
GET /jobs
Mengembalikan daftar paginasi tugas di organisasi Anda. Memerlukan scope read.
Parameter query
| Parameter | Tipe | Deskripsi |
|---|---|---|
page | number | Nomor halaman (default: 1) |
limit | number | Item per halaman (default: 20, maks: 100) |
status | string | Filter berdasarkan status: CREATED, ASSIGNED, IN_PROGRESS, COMPLETED, CANCELLED |
customerId | string | Filter berdasarkan ID pelanggan |
locationId | string | Filter berdasarkan ID lokasi |
priority | string | Filter berdasarkan prioritas: LOW, NORMAL, HIGH |
targetDate | string | Filter berdasarkan tanggal (YYYY-MM-DD) — mengembalikan tugas dengan jendela waktu yang tumpang tindih dengan tanggal ini |
Contoh request
curl "https://api.formict.com/v1/public/jobs?status=CREATED&limit=10" \
-H "Authorization: Bearer fmct_live_xxxxxxxx" Contoh response
{
"data": {
"jobs": [
{
"id": "clx1abc...",
"title": "AC Maintenance",
"description": "Annual AC unit service",
"status": "CREATED",
"priority": "NORMAL",
"customerId": "clx2def...",
"locationId": "clx3ghi...",
"jobLatitude": "-6.2088",
"jobLongitude": "106.8456",
"serviceDuration": 3600,
"timeWindowType": "HARD",
"earliestStart": "2025-03-15T08:00:00.000Z",
"latestEnd": "2025-03-15T12:00:00.000Z",
"scheduledStart": null,
"scheduledEnd": null,
"assignedUserId": null,
"startedAt": null,
"completedAt": null,
"createdAt": "2025-03-14T10:00:00.000Z",
"updatedAt": "2025-03-14T10:00:00.000Z",
"customer": { "id": "clx2def...", "name": "PT Sejahtera" },
"assignedUser": null,
"location": { "id": "clx3ghi...", "name": "Jakarta Office" }
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 1,
"totalPages": 1
}
},
"message": "Success"
} GET /jobs/:id
Mengembalikan satu tugas dengan detail lengkap termasuk pelanggan, pekerja yang ditugaskan, tag, dan permintaan kapasitas. Memerlukan scope read.
Parameter path
| Parameter | Tipe | Deskripsi |
|---|---|---|
id | string | ID tugas |
Contoh response
{
"data": {
"job": {
"id": "clx1abc...",
"title": "AC Maintenance",
"description": "Annual AC unit service",
"status": "CREATED",
"priority": "NORMAL",
"customerId": "clx2def...",
"locationId": "clx3ghi...",
"jobLatitude": "-6.2088",
"jobLongitude": "106.8456",
"serviceDuration": 3600,
"timeWindowType": "HARD",
"earliestStart": "2025-03-15T08:00:00.000Z",
"latestEnd": "2025-03-15T12:00:00.000Z",
"scheduledStart": null,
"scheduledEnd": null,
"assignedUserId": null,
"shiftId": null,
"startedAt": null,
"completedAt": null,
"actualDuration": null,
"createdAt": "2025-03-14T10:00:00.000Z",
"updatedAt": "2025-03-14T10:00:00.000Z",
"customer": {
"id": "clx2def...",
"name": "PT Sejahtera",
"address": "Jl. Sudirman 100",
"latitude": "-6.2088",
"longitude": "106.8456"
},
"assignedUser": null,
"location": { "id": "clx3ghi...", "name": "Jakarta Office" },
"tags": [
{ "tag": { "id": "clx4jkl...", "name": "HVAC" } }
],
"demands": [
{
"capacityDimension": { "id": "clx5mno...", "key": "weight", "label": "Weight" },
"requiredValue": 50
}
]
}
},
"message": "Success"
} POST /jobs
Membuat tugas baru. Memerlukan scope write. Mengembalikan 201 Created.
Body request
| Field | Tipe | Wajib | Deskripsi |
|---|---|---|---|
title | string | Ya | Judul tugas (minimal 1 karakter) |
customerId | string | Tidak | ID pelanggan |
locationId | string | Tidak | ID lokasi/depot |
description | string | Tidak | Deskripsi detail |
jobLatitude | number | Tidak | Latitude lokasi tugas |
jobLongitude | number | Tidak | Longitude lokasi tugas |
priority | string | Tidak | LOW, NORMAL, atau HIGH |
serviceDuration | number | Tidak | Durasi dalam detik (default: 900) |
timeWindowType | string | Tidak | HARD atau SOFT (default: HARD) |
earliestStart | string | Tidak | Datetime ISO 8601 |
latestEnd | string | Tidak | Datetime ISO 8601 (harus setelah earliestStart) |
Contoh request
curl -X POST "https://api.formict.com/v1/public/jobs" \
-H "Authorization: Bearer fmct_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"title": "AC Maintenance",
"customerId": "clx2def...",
"description": "Annual AC unit service",
"priority": "NORMAL",
"serviceDuration": 3600,
"timeWindowType": "HARD",
"earliestStart": "2025-03-15T08:00:00.000Z",
"latestEnd": "2025-03-15T12:00:00.000Z"
}' Kasus error
400— Fieldtitleyang wajib tidak ada400—earliestStartsetelahlatestEnd400— ID pelanggan atau lokasi tidak ditemukan di organisasi Anda
PATCH /jobs/:id
Memperbarui tugas yang sudah ada. Hanya sertakan field yang ingin Anda ubah. Memerlukan scope write.
Parameter path
| Parameter | Tipe | Deskripsi |
|---|---|---|
id | string | ID tugas |
Body request
Field yang sama seperti POST /jobs, semua opsional. Hanya sertakan field yang ingin Anda ubah.
Contoh request
curl -X PATCH "https://api.formict.com/v1/public/jobs/clx1abc..." \
-H "Authorization: Bearer fmct_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "priority": "HIGH", "serviceDuration": 7200 }' Kasus error
404— Tugas tidak ditemukan422— Tidak dapat memperbarui tugas dengan statusCOMPLETEDatauCANCELLED
DELETE /jobs/:id
Menghapus tugas secara soft-delete. Tugas ditandai sebagai dihapus tetapi tetap disimpan di database untuk retensi data. Memerlukan scope write.
Parameter path
| Parameter | Tipe | Deskripsi |
|---|---|---|
id | string | ID tugas |
Contoh request
curl -X DELETE "https://api.formict.com/v1/public/jobs/clx1abc..." \
-H "Authorization: Bearer fmct_live_xxxxxxxx" Kasus error
404— Tugas tidak ditemukan422— Tidak dapat menghapus tugas yang berstatusIN_PROGRESS
Pelanggan
Pelanggan merepresentasikan orang atau bisnis di mana pekerjaan lapangan dilakukan. Setiap pelanggan memiliki lokasi layanan dengan koordinat GPS yang digunakan untuk optimasi rute.
GET /customers
Mengembalikan daftar paginasi pelanggan. Memerlukan scope read.
Parameter query
| Parameter | Tipe | Deskripsi |
|---|---|---|
page | number | Nomor halaman (default: 1) |
limit | number | Item per halaman (default: 50, maks: 100) |
search | string | Cari berdasarkan nama atau alamat (tidak peka huruf besar/kecil) |
Contoh response
{
"data": {
"customers": [
{
"id": "clx2def...",
"name": "PT Sejahtera",
"address": "Jl. Sudirman 100, Jakarta",
"latitude": "-6.2088",
"longitude": "106.8456",
"serviceDuration": 1800,
"priority": "NORMAL",
"timeWindowType": "HARD",
"operationalStart": "08:00",
"operationalEnd": "17:00",
"createdAt": "2025-01-10T08:00:00.000Z",
"updatedAt": "2025-01-10T08:00:00.000Z"
}
],
"pagination": { "page": 1, "limit": 50, "total": 1, "totalPages": 1 }
},
"message": "Success"
} GET /customers/:id
Mengembalikan satu pelanggan dengan semua field. Memerlukan scope read.
POST /customers
Membuat pelanggan baru. Memerlukan scope write. Mengembalikan 201 Created.
Body request
| Field | Tipe | Wajib | Deskripsi |
|---|---|---|---|
name | string | Ya | Nama pelanggan (minimal 1 karakter) |
latitude | number | Ya | Latitude lokasi layanan |
longitude | number | Ya | Longitude lokasi layanan |
address | string | Tidak | Alamat jalan |
serviceDuration | number | Tidak | Waktu layanan default dalam detik |
priority | string | Tidak | LOW, NORMAL, atau HIGH |
timeWindowType | string | Tidak | HARD atau SOFT |
operationalStart | string | Tidak | Waktu buka dalam format HH:MM |
operationalEnd | string | Tidak | Waktu tutup dalam format HH:MM |
Contoh request
curl -X POST "https://api.formict.com/v1/public/customers" \
-H "Authorization: Bearer fmct_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "PT Sejahtera",
"address": "Jl. Sudirman 100, Jakarta",
"latitude": -6.2088,
"longitude": 106.8456,
"serviceDuration": 1800,
"operationalStart": "08:00",
"operationalEnd": "17:00"
}' PATCH /customers/:id
Memperbarui pelanggan yang sudah ada. Hanya sertakan field yang ingin Anda ubah. Memerlukan scope write.
Body request
Field yang sama seperti POST /customers, semua opsional.
Kendaraan
Kendaraan merepresentasikan armada Anda. Setiap kendaraan ditugaskan ke lokasi (depot) dan memiliki batasan kapasitas, parameter biaya, dan tag kemampuan.
GET /vehicles
Mengembalikan daftar paginasi kendaraan dengan tag dan info kapasitas. Memerlukan scope read.
Parameter query
| Parameter | Tipe | Deskripsi |
|---|---|---|
page | number | Nomor halaman (default: 1) |
limit | number | Item per halaman (default: 50, maks: 100) |
locationId | string | Filter berdasarkan ID depot/lokasi |
isActive | boolean | Filter berdasarkan status aktif |
Contoh response
{
"data": {
"vehicles": [
{
"id": "clx4jkl...",
"name": "Van-01",
"locationId": "clx3ghi...",
"fixedCost": 50000,
"costPerKm": 500,
"costPerHour": 15000,
"speedFactor": 1.0,
"startLatitude": null,
"startLongitude": null,
"endPolicy": "RETURN_TO_ORIGIN",
"isActive": true,
"createdAt": "2025-01-10T08:00:00.000Z",
"updatedAt": "2025-01-10T08:00:00.000Z",
"location": { "id": "clx3ghi...", "name": "Jakarta Office" },
"tags": [
{ "tag": { "id": "clx5mno...", "name": "HVAC" } }
],
"capacities": [
{
"capacityDimension": { "id": "clx6pqr...", "key": "weight", "label": "Weight" },
"maxValue": 1000
}
]
}
],
"pagination": { "page": 1, "limit": 50, "total": 1, "totalPages": 1 }
},
"message": "Success"
} GET /vehicles/:id
Mengembalikan satu kendaraan dengan tag dan kapasitas. Memerlukan scope read.
Lokasi
Lokasi adalah hub operasional atau depot Anda. Kendaraan memulai dan mengakhiri rute mereka di lokasi yang ditugaskan.
GET /locations
Mengembalikan semua lokasi di organisasi Anda. Memerlukan scope read.
Parameter query
| Parameter | Tipe | Deskripsi |
|---|---|---|
page | number | Nomor halaman (default: 1) |
limit | number | Item per halaman (default: 50, maks: 100) |
isActive | boolean | Filter berdasarkan status aktif |
Contoh response
{
"data": {
"locations": [
{
"id": "clx3ghi...",
"name": "Jakarta Office",
"code": "JKT",
"description": "Main headquarters",
"address": "Jl. Sudirman 1, Jakarta",
"latitude": "-6.1751",
"longitude": "106.8272",
"timezone": "Asia/Jakarta",
"isPrimary": true,
"isActive": true,
"createdAt": "2025-01-01T00:00:00.000Z",
"updatedAt": "2025-01-01T00:00:00.000Z"
}
],
"pagination": { "page": 1, "limit": 50, "total": 1, "totalPages": 1 }
},
"message": "Success"
} GET /locations/:id
Mengembalikan satu lokasi dengan semua field. Memerlukan scope read.
Shift
Shift mendefinisikan kapan kendaraan dan pekerja tersedia. Pengoptimal rute menggunakan jendela waktu shift sebagai jendela operasi yang tersedia untuk setiap kendaraan.
GET /shifts
Mengembalikan daftar paginasi template shift dengan detail pekerja, lokasi, kendaraan, dan istirahat. Memerlukan scope read.
Parameter query
| Parameter | Tipe | Deskripsi |
|---|---|---|
page | number | Nomor halaman (default: 1) |
limit | number | Item per halaman (default: 50, maks: 100) |
locationId | string | Filter berdasarkan ID lokasi |
userId | string | Filter berdasarkan ID pekerja |
day | string | Filter berdasarkan hari dalam seminggu (misal, MONDAY) |
Contoh response
{
"data": {
"shifts": [
{
"id": "clx7stu...",
"userId": "clx8vwx...",
"locationId": "clx3ghi...",
"vehicleId": "clx4jkl...",
"day": "MONDAY",
"startTime": "08:00",
"endTime": "17:00",
"isGenerated": false,
"createdAt": "2025-01-10T08:00:00.000Z",
"updatedAt": "2025-01-10T08:00:00.000Z",
"user": { "id": "clx8vwx...", "name": "John", "email": "[email protected]" },
"location": { "id": "clx3ghi...", "name": "Jakarta Office" },
"vehicle": { "id": "clx4jkl...", "name": "Van-01" },
"breaks": [
{ "id": "clx9yza...", "startTime": "12:00", "endTime": "13:00", "isPaid": false }
]
}
],
"pagination": { "page": 1, "limit": 50, "total": 1, "totalPages": 1 }
},
"message": "Success"
} GET /shifts/:id
Mengembalikan satu shift dengan detail pekerja, lokasi, kendaraan, dan istirahat. Memerlukan scope read.
Enum & Konstanta
Berikut adalah nilai-nilai valid untuk field enum yang digunakan di seluruh API.
JobStatus
| Nilai | Deskripsi |
|---|---|
CREATED | Tugas ada tetapi belum ditugaskan |
ASSIGNED | Tugas telah ditugaskan ke kendaraan/pekerja |
IN_PROGRESS | Pekerja telah memulai tugas |
COMPLETED | Tugas telah selesai |
CANCELLED | Tugas telah dibatalkan |
JobPriority
| Nilai | Deskripsi |
|---|---|
LOW | Prioritas rendah |
NORMAL | Prioritas normal (default) |
HIGH | Prioritas tinggi — diutamakan oleh pengoptimal |
TimeWindowType
| Nilai | Deskripsi |
|---|---|
HARD | Ketat — tugas dilewati jika tidak muat dalam jendela waktu |
SOFT | Fleksibel — solver memberikan penalti tetapi tetap menugaskan |
VehicleEndPolicy
| Nilai | Deskripsi |
|---|---|
RETURN_TO_ORIGIN | Kendaraan kembali ke titik asal rutenya setelah tugas terakhir |
END_AT_LAST_JOB | Rute berakhir di mana pun tugas terakhir berada |
Hari dalam seminggu
| Nilai |
|---|
MONDAY |
TUESDAY |
WEDNESDAY |
THURSDAY |
FRIDAY |
SATURDAY |
SUNDAY |
Format durasi
Semua field durasi (serviceDuration, dll.) dalam satuan detik.
Misalnya, 30 menit = 1800, 1 jam = 3600.
Format datetime
Semua field datetime menggunakan format ISO 8601 dalam UTC:
2025-03-15T08:00:00.000Z
Format koordinat
Latitude dan longitude disimpan sebagai string di database tetapi diterima sebagai angka
di body request. Gunakan derajat desimal (misal, -6.2088 untuk latitude,
106.8456 untuk longitude).
Webhook
Formict dapat mengirim request HTTP POST ke server Anda ketika event tertentu terjadi. Webhook dikonfigurasi melalui Automasi di dashboard menggunakan tipe aksi Kirim Webhook.
Menyiapkan webhook
- Buka Settings → Automations
- Buat automasi baru
- Pilih event pemicu (misal,
JOB_COMPLETED) - Pilih Kirim Webhook sebagai aksi
- Masukkan URL webhook Anda
- Aktifkan automasi
Payload webhook
Webhook mengirim request JSON POST ke URL Anda dengan data event:
{
"event": "JOB_COMPLETED",
"timestamp": "2025-03-15T14:30:00.000Z",
"data": {
"jobId": "clx1abc...",
"title": "AC Maintenance",
"status": "COMPLETED",
"customerId": "clx2def...",
"assignedUserId": "clx8vwx...",
"completedAt": "2025-03-15T14:30:00.000Z"
}
} Event pemicu yang tersedia
| Event | Deskripsi |
|---|---|
JOB_CREATED | Tugas baru dibuat |
JOB_UPDATED | Detail tugas diubah |
STATUS_CHANGED | Status tugas berubah |
JOB_ASSIGNED | Tugas ditugaskan ke pekerja |
JOB_UNASSIGNED | Tugas dicopot dari pekerja |
JOB_COMPLETED | Tugas ditandai sebagai selesai |
JOB_CANCELLED | Tugas dibatalkan |
FORM_SUBMITTED | Pengiriman formulir diterima |
Perilaku percobaan ulang
Jika endpoint webhook Anda mengembalikan kode status non-2xx, request tidak akan dicoba ulang. Periksa log eksekusi automasi di dashboard untuk melihat status pengiriman dan detail error apa pun.
Changelog
v1.0 — Saat ini
- CRUD Tugas (daftar, ambil, buat, perbarui, hapus)
- CRUD Pelanggan (daftar, ambil, buat, perbarui)
- Kendaraan (daftar, ambil) dengan tag dan kapasitas
- Lokasi (daftar, ambil)
- Shift (daftar, ambil) dengan istirahat
- Autentikasi API key dengan scope (read, write, admin)
- Pengiriman webhook melalui automasi
Butuh bantuan? Hubungi dukungan atau lihat dokumentasi pengguna untuk panduan langkah demi langkah.