Lewati ke konten
Aktivo

Developers

Dokumentasi Aktivo API

Developers

Dokumentasi Aktivo API

Integrasikan Aktivo dengan sistem lain lewat REST API. Buat token di Settings → API tokens (owner/HRD).

API v1 memakai Bearer token perusahaan. Mulai dari autentikasi, pilih scope, lalu panggil endpoint per grup resource di bawah.

Base URL

https://aktivo.ngarya.com/api/v1

List endpoint mendukung ?page= dan ?per_page= (maks 100). Beberapa endpoint mendukung filter seperti status, search, from, to, updated_since.

Authentication

Kirim Authorization Bearer dengan token perusahaan. Endpoint yang scoped cabang wajib menyertakan X-Branch-Id (id cabang dari GET /branches).

Authorization: Bearer akt_YOUR_TOKEN
X-Branch-Id: 1
Accept: application/json
Content-Type: application/json

Scopes

  • branches:read - Daftar cabang
  • employees:read / employees:write - Baca / tulis karyawan
  • departments:read / positions:read - Master organisasi
  • attendance:read - Riwayat absensi
  • requests:read / requests:write - Cuti & HR request
  • meetings:read / meetings:write - Rapat

API tokens

Masuk sebagai owner atau HRD → Settings → API tokens → buat token, pilih scope, set kedaluwarsa, salin plaintext sekali saja.

Daftar endpoint v1

Method Path Catatan
GET /branches Tanpa X-Branch-Id
GET /departments Perlu X-Branch-Id
GET /positions Perlu X-Branch-Id
GET/POST /employees Perlu X-Branch-Id
GET/PATCH /employees/{id} Perlu X-Branch-Id
GET /attendance Filter from/to, employee_id
GET/POST /requests Cuti, sakit, dinas, lembur
GET/POST /meetings Tenant-wide (tanpa branch)
GET/PATCH /meetings/{id} Update agenda/minutes

Branches

Ambil daftar cabang untuk dipakai sebagai X-Branch-Id pada endpoint lain.

GET /branches HTTP 200

Daftar cabang

Scope: branches:read · X-Branch-Id tidak diperlukan

cURL

curl -s -X GET "https://aktivo.ngarya.com/api/v1/branches?page=1&per_page=50" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json"

Query params

{
    "page": 1,
    "per_page": 50
}

Response JSON (200)

{
    "data": [
        {
            "id": 1,
            "external_branch_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
            "slug": "main",
            "name": "Main",
            "is_default": true,
            "is_active": true
        }
    ],
    "links": {
        "first": "https://aktivo.example/api/v1/branches?page=1",
        "last": "https://aktivo.example/api/v1/branches?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 1
    }
}

Organization

Master departemen dan jabatan untuk sync karyawan.

GET /departments HTTP 200

Daftar departemen

Scope: departments:read · X-Branch-Id wajib

cURL

curl -s -X GET "https://aktivo.ngarya.com/api/v1/departments?page=1&per_page=50" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "X-Branch-Id: 1"

Query params

{
    "page": 1,
    "per_page": 50
}

Response JSON (200)

{
    "data": [
        {
            "id": 2,
            "name": "Human Resources",
            "description": "HR team"
        }
    ],
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 1
    }
}
GET /positions HTTP 200

Daftar jabatan

Scope: positions:read · X-Branch-Id wajib

cURL

curl -s -X GET "https://aktivo.ngarya.com/api/v1/positions?department_id=2&page=1" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "X-Branch-Id: 1"

Query params

{
    "department_id": 2,
    "page": 1
}

Response JSON (200)

{
    "data": [
        {
            "id": 5,
            "department_id": 2,
            "name": "HR Staff",
            "description": null
        }
    ],
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 1
    }
}

Employees

List, create, dan update data karyawan per cabang.

GET /employees HTTP 200

Daftar karyawan

Scope: employees:read · X-Branch-Id wajib

cURL

curl -s -X GET "https://aktivo.ngarya.com/api/v1/employees?page=1&per_page=25&status=active&search=Rina" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "X-Branch-Id: 1"

Query params

{
    "page": 1,
    "per_page": 25,
    "status": "active",
    "search": "Rina"
}

Response JSON (200)

{
    "data": [
        {
            "id": 12,
            "employee_number": "E-100",
            "full_name": "Rina Wijaya",
            "email": "[email protected]",
            "phone": "08123456789",
            "branch_id": 1,
            "department_id": 2,
            "position_id": 5,
            "manager_id": null,
            "join_date": "2025-01-15",
            "employment_status": "permanent",
            "status": "active",
            "created_at": "2025-01-15T02:00:00+07:00",
            "updated_at": "2026-08-01T10:00:00+07:00"
        }
    ],
    "meta": {
        "current_page": 1,
        "per_page": 25,
        "total": 1
    }
}
POST /employees HTTP 201

Tambah karyawan

Scope: employees:write · X-Branch-Id wajib

cURL

curl -s -X POST "https://aktivo.ngarya.com/api/v1/employees" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "X-Branch-Id: 1" \
  -H "Content-Type: application/json" \
  -d '{"employee_number":"E-101","full_name":"Budi Santoso","email":"[email protected]","phone":"08129876543","department_id":2,"position_id":5,"join_date":"2026-08-01","employment_status":"permanent","status":"active"}'

Request body

{
    "employee_number": "E-101",
    "full_name": "Budi Santoso",
    "email": "[email protected]",
    "phone": "08129876543",
    "department_id": 2,
    "position_id": 5,
    "join_date": "2026-08-01",
    "employment_status": "permanent",
    "status": "active"
}

Response JSON (201)

{
    "data": {
        "id": 18,
        "employee_number": "E-101",
        "full_name": "Budi Santoso",
        "email": "[email protected]",
        "phone": "08129876543",
        "branch_id": 1,
        "department_id": 2,
        "position_id": 5,
        "manager_id": null,
        "join_date": "2026-08-01",
        "employment_status": "permanent",
        "status": "active",
        "created_at": "2026-08-27T08:00:00+07:00",
        "updated_at": "2026-08-27T08:00:00+07:00"
    }
}
PATCH /employees/18 HTTP 200

Update karyawan

Scope: employees:write · X-Branch-Id wajib

cURL

curl -s -X PATCH "https://aktivo.ngarya.com/api/v1/employees/18" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "X-Branch-Id: 1" \
  -H "Content-Type: application/json" \
  -d '{"phone":"08121112223","status":"active"}'

Request body

{
    "phone": "08121112223",
    "status": "active"
}

Response JSON (200)

{
    "data": {
        "id": 18,
        "employee_number": "E-101",
        "full_name": "Budi Santoso",
        "email": "[email protected]",
        "phone": "08121112223",
        "branch_id": 1,
        "department_id": 2,
        "position_id": 5,
        "manager_id": null,
        "join_date": "2026-08-01",
        "employment_status": "permanent",
        "status": "active",
        "created_at": "2026-08-27T08:00:00+07:00",
        "updated_at": "2026-08-27T09:15:00+07:00"
    }
}

Attendance

Baca riwayat absensi. Clock-in/out tidak tersedia di API v1.

GET /attendance HTTP 200

Riwayat absensi

Scope: attendance:read · X-Branch-Id wajib

cURL

curl -s -X GET "https://aktivo.ngarya.com/api/v1/attendance?from=2026-08-01&to=2026-08-31&employee_id=12&page=1" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "X-Branch-Id: 1"

Query params

{
    "from": "2026-08-01",
    "to": "2026-08-31",
    "employee_id": 12,
    "page": 1
}

Response JSON (200)

{
    "data": [
        {
            "id": 901,
            "employee_id": 12,
            "branch_id": 1,
            "attendance_date": "2026-08-27",
            "clock_in_at": "2026-08-27T08:02:11+07:00",
            "clock_out_at": "2026-08-27T17:05:44+07:00",
            "status": "present",
            "notes": null
        }
    ],
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 1
    }
}

HR Requests

Cuti, sakit, dinas, dan lembur - buat dan pantau status.

POST /requests HTTP 201

Buat pengajuan cuti

Scope: requests:write · X-Branch-Id wajib

cURL

curl -s -X POST "https://aktivo.ngarya.com/api/v1/requests" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "X-Branch-Id: 1" \
  -H "Content-Type: application/json" \
  -d '{"employee_id":12,"type":"leave","description":"Family event","start_date":"2026-09-10","end_date":"2026-09-12","leave_type_id":1,"total_days":3,"reason":"Family event","submit":true}'

Request body

{
    "employee_id": 12,
    "type": "leave",
    "description": "Family event",
    "start_date": "2026-09-10",
    "end_date": "2026-09-12",
    "leave_type_id": 1,
    "total_days": 3,
    "reason": "Family event",
    "submit": true
}

Response JSON (201)

{
    "data": {
        "id": 44,
        "request_number": "HR-2026-0044",
        "employee_id": 12,
        "type": "leave",
        "status": "pending",
        "description": "Family event",
        "start_date": "2026-09-10",
        "end_date": "2026-09-12",
        "start_time": null,
        "end_time": null,
        "submitted_at": "2026-08-27T10:00:00+07:00",
        "created_at": "2026-08-27T10:00:00+07:00",
        "updated_at": "2026-08-27T10:00:00+07:00",
        "leave_detail": {
            "leave_type_id": 1,
            "total_days": 3,
            "reason": "Family event"
        },
        "sick_leave_detail": null,
        "business_visit_detail": null,
        "overtime_detail": null
    }
}
GET /requests HTTP 200

Daftar HR request

Scope: requests:read · X-Branch-Id wajib

cURL

curl -s -X GET "https://aktivo.ngarya.com/api/v1/requests?type=leave&status=pending&page=1" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "X-Branch-Id: 1"

Query params

{
    "type": "leave",
    "status": "pending",
    "page": 1
}

Response JSON (200)

{
    "data": [
        {
            "id": 44,
            "request_number": "HR-2026-0044",
            "employee_id": 12,
            "type": "leave",
            "status": "pending",
            "description": "Family event",
            "start_date": "2026-09-10",
            "end_date": "2026-09-12",
            "start_time": null,
            "end_time": null,
            "submitted_at": "2026-08-27T10:00:00+07:00",
            "created_at": "2026-08-27T10:00:00+07:00",
            "updated_at": "2026-08-27T10:00:00+07:00",
            "leave_detail": {
                "leave_type_id": 1,
                "total_days": 3,
                "reason": "Family event"
            }
        }
    ],
    "meta": {
        "current_page": 1,
        "per_page": 25,
        "total": 1
    }
}

Meetings (Rapat)

Jadwal dan notulen rapat. Tenant-wide (tanpa X-Branch-Id).

POST /meetings HTTP 201

Buat rapat

Scope: meetings:write · X-Branch-Id tidak diperlukan

cURL

curl -s -X POST "https://aktivo.ngarya.com/api/v1/meetings" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"title":"Sprint planning","meeting_number":"MTG-001","meeting_type":"internal","meeting_date":"2026-09-01","start_time":"09:00","end_time":"10:00","location":"Room A","organizer_employee_id":12,"description":"Weekly planning","agenda":"1. Status\n2. Blockers","is_confidential":false,"participant_ids":[12,18]}'

Request body

{
    "title": "Sprint planning",
    "meeting_number": "MTG-001",
    "meeting_type": "internal",
    "meeting_date": "2026-09-01",
    "start_time": "09:00",
    "end_time": "10:00",
    "location": "Room A",
    "organizer_employee_id": 12,
    "description": "Weekly planning",
    "agenda": "1. Status\n2. Blockers",
    "is_confidential": false,
    "participant_ids": [
        12,
        18
    ]
}

Response JSON (201)

{
    "data": {
        "id": 7,
        "title": "Sprint planning",
        "meeting_number": "MTG-001",
        "meeting_type": "internal",
        "meeting_date": "2026-09-01",
        "start_time": "09:00",
        "end_time": "10:00",
        "location": "Room A",
        "organizer_employee_id": 12,
        "description": "Weekly planning",
        "agenda": "1. Status\n2. Blockers",
        "discussion": null,
        "decisions": null,
        "additional_notes": null,
        "is_confidential": false,
        "participant_ids": [
            12,
            18
        ],
        "created_at": "2026-08-27T11:00:00+07:00",
        "updated_at": "2026-08-27T11:00:00+07:00"
    }
}
PATCH /meetings/7 HTTP 200

Update notulen rapat

Scope: meetings:write · X-Branch-Id tidak diperlukan

cURL

curl -s -X PATCH "https://aktivo.ngarya.com/api/v1/meetings/7" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"discussion":"Agreed to ship employee API this week.","decisions":"Owner: Budi. Due: Friday."}'

Request body

{
    "discussion": "Agreed to ship employee API this week.",
    "decisions": "Owner: Budi. Due: Friday."
}

Response JSON (200)

{
    "data": {
        "id": 7,
        "title": "Sprint planning",
        "meeting_number": "MTG-001",
        "meeting_type": "internal",
        "meeting_date": "2026-09-01",
        "start_time": "09:00",
        "end_time": "10:00",
        "location": "Room A",
        "organizer_employee_id": 12,
        "description": "Weekly planning",
        "agenda": "1. Status\n2. Blockers",
        "discussion": "Agreed to ship employee API this week.",
        "decisions": "Owner: Budi. Due: Friday.",
        "additional_notes": null,
        "is_confidential": false,
        "participant_ids": [
            12,
            18
        ],
        "created_at": "2026-08-27T11:00:00+07:00",
        "updated_at": "2026-08-27T12:30:00+07:00"
    }
}
GET /meetings HTTP 200

Daftar rapat

Scope: meetings:read · X-Branch-Id tidak diperlukan

cURL

curl -s -X GET "https://aktivo.ngarya.com/api/v1/meetings?from=2026-09-01&to=2026-09-30&page=1" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json"

Query params

{
    "from": "2026-09-01",
    "to": "2026-09-30",
    "page": 1
}

Response JSON (200)

{
    "data": [
        {
            "id": 7,
            "title": "Sprint planning",
            "meeting_number": "MTG-001",
            "meeting_type": "internal",
            "meeting_date": "2026-09-01",
            "start_time": "09:00",
            "end_time": "10:00",
            "location": "Room A",
            "organizer_employee_id": 12,
            "description": "Weekly planning",
            "agenda": "1. Status\n2. Blockers",
            "discussion": "Agreed to ship employee API this week.",
            "decisions": "Owner: Budi. Due: Friday.",
            "additional_notes": null,
            "is_confidential": false,
            "participant_ids": [
                12,
                18
            ],
            "created_at": "2026-08-27T11:00:00+07:00",
            "updated_at": "2026-08-27T12:30:00+07:00"
        }
    ],
    "meta": {
        "current_page": 1,
        "per_page": 25,
        "total": 1
    }
}

Errors

Contoh response error yang sering muncul.

GET /employees HTTP 401

Token tidak valid

Scope: - · X-Branch-Id wajib

cURL

curl -s -X GET "https://aktivo.ngarya.com/api/v1/employees" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "X-Branch-Id: 1"

Response JSON (401)

{
    "message": "Unauthenticated."
}
GET /employees HTTP 422

X-Branch-Id hilang

Scope: employees:read · X-Branch-Id tidak diperlukan

cURL

curl -s -X GET "https://aktivo.ngarya.com/api/v1/employees" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json"

Response JSON (422)

{
    "message": "X-Branch-Id header is required."
}
POST /employees HTTP 403

Scope tidak cukup

Scope: employees:read · X-Branch-Id wajib

cURL

curl -s -X POST "https://aktivo.ngarya.com/api/v1/employees" \
  -H "Authorization: Bearer akt_YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "X-Branch-Id: 1" \
  -H "Content-Type: application/json" \
  -d '{"employee_number":"E-102","full_name":"Test","status":"active"}'

Request body

{
    "employee_number": "E-102",
    "full_name": "Test",
    "status": "active"
}

Response JSON (403)

{
    "message": "This token is missing the required scope: employees:write"
}