API v1.0

Referensi API

Integrasikan Formict dengan sistem Anda menggunakan API Publik. Kelola tugas, pelanggan, kendaraan, lokasi, dan shift secara programatis.

Base URL
https://api.formict.com/v1/public

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
200Berhasil
201Resource berhasil dibuat
400Request tidak valid (error validasi)
401Tidak terotorisasi (API key tidak ada atau tidak valid)
403Terlarang (scope tidak mencukupi)
404Resource tidak ditemukan
422Entitas tidak dapat diproses (error logika bisnis)
429Batas rate terlampaui
500Error 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_FOUNDResource yang diminta tidak ada atau telah dihapus
VALIDATION_ERRORBody request gagal validasi (field hilang atau tidak valid)
TERMINAL_STATETidak dapat mengubah tugas dengan status COMPLETED atau CANCELLED
JOB_IN_PROGRESSTidak dapat menghapus tugas yang sedang berlangsung
FORBIDDENAPI key tidak memiliki scope yang diperlukan untuk operasi ini
RATE_LIMITEDTerlalu 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-LimitMaksimum request per menit
X-RateLimit-RemainingSisa request dalam jendela waktu saat ini
X-RateLimit-ResetDetik 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

ParameterTipeDeskripsi
pagenumberNomor halaman (default: 1)
limitnumberItem per halaman (default: 20, maks: 100)
statusstringFilter berdasarkan status: CREATED, ASSIGNED, IN_PROGRESS, COMPLETED, CANCELLED
customerIdstringFilter berdasarkan ID pelanggan
locationIdstringFilter berdasarkan ID lokasi
prioritystringFilter berdasarkan prioritas: LOW, NORMAL, HIGH
targetDatestringFilter 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

ParameterTipeDeskripsi
idstringID 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

FieldTipeWajibDeskripsi
titlestringYaJudul tugas (minimal 1 karakter)
customerIdstringTidakID pelanggan
locationIdstringTidakID lokasi/depot
descriptionstringTidakDeskripsi detail
jobLatitudenumberTidakLatitude lokasi tugas
jobLongitudenumberTidakLongitude lokasi tugas
prioritystringTidakLOW, NORMAL, atau HIGH
serviceDurationnumberTidakDurasi dalam detik (default: 900)
timeWindowTypestringTidakHARD atau SOFT (default: HARD)
earliestStartstringTidakDatetime ISO 8601
latestEndstringTidakDatetime 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 — Field title yang wajib tidak ada
  • 400earliestStart setelah latestEnd
  • 400 — 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

ParameterTipeDeskripsi
idstringID 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 ditemukan
  • 422 — Tidak dapat memperbarui tugas dengan status COMPLETED atau CANCELLED

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

ParameterTipeDeskripsi
idstringID 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 ditemukan
  • 422 — Tidak dapat menghapus tugas yang berstatus IN_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

ParameterTipeDeskripsi
pagenumberNomor halaman (default: 1)
limitnumberItem per halaman (default: 50, maks: 100)
searchstringCari 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

FieldTipeWajibDeskripsi
namestringYaNama pelanggan (minimal 1 karakter)
latitudenumberYaLatitude lokasi layanan
longitudenumberYaLongitude lokasi layanan
addressstringTidakAlamat jalan
serviceDurationnumberTidakWaktu layanan default dalam detik
prioritystringTidakLOW, NORMAL, atau HIGH
timeWindowTypestringTidakHARD atau SOFT
operationalStartstringTidakWaktu buka dalam format HH:MM
operationalEndstringTidakWaktu 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

ParameterTipeDeskripsi
pagenumberNomor halaman (default: 1)
limitnumberItem per halaman (default: 50, maks: 100)
locationIdstringFilter berdasarkan ID depot/lokasi
isActivebooleanFilter 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

ParameterTipeDeskripsi
pagenumberNomor halaman (default: 1)
limitnumberItem per halaman (default: 50, maks: 100)
isActivebooleanFilter 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

ParameterTipeDeskripsi
pagenumberNomor halaman (default: 1)
limitnumberItem per halaman (default: 50, maks: 100)
locationIdstringFilter berdasarkan ID lokasi
userIdstringFilter berdasarkan ID pekerja
daystringFilter 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

NilaiDeskripsi
CREATEDTugas ada tetapi belum ditugaskan
ASSIGNEDTugas telah ditugaskan ke kendaraan/pekerja
IN_PROGRESSPekerja telah memulai tugas
COMPLETEDTugas telah selesai
CANCELLEDTugas telah dibatalkan

JobPriority

NilaiDeskripsi
LOWPrioritas rendah
NORMALPrioritas normal (default)
HIGHPrioritas tinggi — diutamakan oleh pengoptimal

TimeWindowType

NilaiDeskripsi
HARDKetat — tugas dilewati jika tidak muat dalam jendela waktu
SOFTFleksibel — solver memberikan penalti tetapi tetap menugaskan

VehicleEndPolicy

NilaiDeskripsi
RETURN_TO_ORIGINKendaraan kembali ke titik asal rutenya setelah tugas terakhir
END_AT_LAST_JOBRute 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

  1. Buka Settings → Automations
  2. Buat automasi baru
  3. Pilih event pemicu (misal, JOB_COMPLETED)
  4. Pilih Kirim Webhook sebagai aksi
  5. Masukkan URL webhook Anda
  6. 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

EventDeskripsi
JOB_CREATEDTugas baru dibuat
JOB_UPDATEDDetail tugas diubah
STATUS_CHANGEDStatus tugas berubah
JOB_ASSIGNEDTugas ditugaskan ke pekerja
JOB_UNASSIGNEDTugas dicopot dari pekerja
JOB_COMPLETEDTugas ditandai sebagai selesai
JOB_CANCELLEDTugas dibatalkan
FORM_SUBMITTEDPengiriman 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.