API Organizations
Referensi API lengkap untuk mengelola organisasi, anggota, kebijakan, branding, dan SSO di ARSAKA PUGUH.
Konvensi API
Semua response API PUGUH dikembalikan langsung sebagai JSON (tanpa wrapper {success, data}). Kode status HTTP menunjukkan keberhasilan atau kegagalan. Endpoint berpaginasi mengembalikan {items, total, page, page_size, has_next, has_prev}.
Ringkasan Endpoint
Organization CRUD
| Method | Endpoint | Deskripsi |
|---|---|---|
GET | /api/v1/organizations | Daftar organisasi |
POST | /api/v1/organizations | Buat organisasi |
GET | /api/v1/organizations/{id} | Detail organisasi |
PATCH | /api/v1/organizations/{id} | Perbarui organisasi |
DELETE | /api/v1/organizations/{id} | Hapus organisasi (soft delete) |
Members
| Method | Endpoint | Deskripsi |
|---|---|---|
GET | /api/v1/organizations/{id}/members | Daftar anggota |
POST | /api/v1/organizations/{id}/members | Undang anggota |
PATCH | /api/v1/organizations/{id}/members/{user_id} | Perbarui role anggota |
DELETE | /api/v1/organizations/{id}/members/{user_id} | Hapus anggota |
Policies (Paket Business+)
| Method | Endpoint | Deskripsi |
|---|---|---|
GET | /api/v1/organizations/{id}/policies | Lihat kebijakan organisasi |
PUT | /api/v1/organizations/{id}/policies | Perbarui kebijakan organisasi |
Branding (Paket Business+)
| Method | Endpoint | Deskripsi |
|---|---|---|
GET | /api/v1/organizations/{id}/branding | Lihat konfigurasi branding |
PUT | /api/v1/organizations/{id}/branding | Perbarui konfigurasi branding |
SSO (Paket Business+)
| Method | Endpoint | Deskripsi |
|---|---|---|
POST | /api/v1/sso/configurations | Buat konfigurasi SSO |
GET | /api/v1/sso/configurations/{org_id} | Lihat konfigurasi SSO |
PUT | /api/v1/sso/configurations/{org_id} | Perbarui konfigurasi SSO |
Daftar Organisasi
Mengembalikan daftar berpaginasi dari organisasi yang dimiliki pengguna yang terautentikasi.
GET /api/v1/organizations Parameter Query
| Parameter | Tipe | Default | Deskripsi |
|---|---|---|---|
page | int | 1 | Nomor halaman |
page_size | int | 20 | Item per halaman (maks 100) |
type | string | — | Filter berdasarkan tipe: personal atau team |
search | string | — | Cari berdasarkan nama organisasi |
Response (200 OK)
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Acme Corp",
"slug": "acme-corp",
"type": "team",
"plan": "business",
"member_count": 24,
"is_active": true,
"created_at": "2026-01-15T08:00:00Z",
"updated_at": "2026-02-10T14:30:00Z"
},
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "Jane's Workspace",
"slug": "janes-workspace",
"type": "personal",
"plan": "free",
"member_count": 1,
"is_active": true,
"created_at": "2026-01-10T06:00:00Z",
"updated_at": "2026-01-10T06:00:00Z"
}
],
"total": 2,
"page": 1,
"page_size": 20,
"has_next": false,
"has_prev": false
} Buat Organisasi
Membuat organisasi tim baru. Setiap pengguna otomatis mendapatkan workspace personal saat mendaftar; endpoint ini untuk membuat organisasi tim tambahan.
POST /api/v1/organizations
Content-Type: application/json Request Body
{
"name": "Acme Corp",
"slug": "acme-corp",
"type": "team"
} Field Request
| Field | Tipe | Wajib | Deskripsi |
|---|---|---|---|
name | string | Ya | Nama tampilan (2-100 karakter) |
slug | string | Tidak | Identifier URL-friendly (otomatis dari nama jika tidak diisi) |
type | string | Tidak | team (default) atau personal |
Response (201 Created)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Acme Corp",
"slug": "acme-corp",
"type": "team",
"plan": "free",
"is_active": true,
"created_at": "2026-02-20T10:00:00Z",
"updated_at": "2026-02-20T10:00:00Z"
} Info
Pengguna yang membuat secara otomatis diberi role owner di organisasi baru.
Detail Organisasi
Mengembalikan informasi detail tentang organisasi tertentu.
GET /api/v1/organizations/{id} Response (200 OK)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Acme Corp",
"slug": "acme-corp",
"type": "team",
"plan": "business",
"member_count": 24,
"application_count": 3,
"is_active": true,
"settings": {
"default_role": "member",
"allow_member_invite": false
},
"created_at": "2026-01-15T08:00:00Z",
"updated_at": "2026-02-10T14:30:00Z"
} Perbarui Organisasi
Memperbarui detail organisasi. Hanya field yang disertakan dalam request body yang diubah.
PATCH /api/v1/organizations/{id}
Content-Type: application/json Request Body
{
"name": "Acme Corporation",
"settings": {
"default_role": "viewer",
"allow_member_invite": true
}
} Field Request
| Field | Tipe | Deskripsi |
|---|---|---|
name | string | Nama tampilan organisasi |
slug | string | Identifier URL-friendly (harus unik) |
settings.default_role | string | Role default untuk anggota baru: member atau viewer |
settings.allow_member_invite | boolean | Apakah anggota non-admin dapat mengundang orang lain |
Response (200 OK)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Acme Corporation",
"slug": "acme-corp",
"type": "team",
"plan": "business",
"is_active": true,
"settings": {
"default_role": "viewer",
"allow_member_invite": true
},
"updated_at": "2026-02-20T11:00:00Z"
} Hapus Organisasi
Soft-delete organisasi. Organisasi dinonaktifkan dan ditandai sebagai dihapus tetapi data disimpan selama 30 hari sebelum penghapusan permanen.
DELETE /api/v1/organizations/{id} Response (200 OK)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"is_active": false,
"deleted_at": "2026-02-20T12:00:00Z"
} Peringatan
Hanya owner organisasi yang dapat menghapus organisasi. Menghapus organisasi menonaktifkan semua aplikasi terkait dan mencabut akses anggota secara langsung.
Daftar Anggota
Mengembalikan daftar berpaginasi dari anggota dalam organisasi.
GET /api/v1/organizations/{id}/members Parameter Query
| Parameter | Tipe | Default | Deskripsi |
|---|---|---|---|
page | int | 1 | Nomor halaman |
page_size | int | 20 | Item per halaman (maks 100) |
role | string | — | Filter berdasarkan role: owner, admin, member, viewer |
search | string | — | Cari berdasarkan nama atau email |
Response (200 OK)
{
"items": [
{
"user_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"email": "jane@acme.com",
"full_name": "Jane Smith",
"role": "owner",
"status": "active",
"accepted_at": "2026-01-15T08:00:00Z"
},
{
"user_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"email": "bob@acme.com",
"full_name": "Bob Johnson",
"role": "admin",
"status": "active",
"accepted_at": "2026-01-20T09:30:00Z"
},
{
"user_id": null,
"email": "new@acme.com",
"full_name": null,
"role": "member",
"status": "pending",
"accepted_at": null
}
],
"total": 3,
"page": 1,
"page_size": 20,
"has_next": false,
"has_prev": false
} Undang Anggota
Mengirimkan email undangan untuk bergabung ke organisasi. Jika email belum memiliki akun PUGUH, pengguna akan diminta untuk mendaftar terlebih dahulu.
POST /api/v1/organizations/{id}/members
Content-Type: application/json Request Body
{
"email": "new@acme.com",
"role": "member"
} Field Request
| Field | Tipe | Wajib | Deskripsi |
|---|---|---|---|
email | string | Ya | Alamat email yang diundang |
role | string | Ya | Role yang diberikan: admin, member, atau viewer |
Response (201 Created)
{
"email": "new@acme.com",
"role": "member",
"status": "pending",
"invited_at": "2026-02-20T10:00:00Z",
"invited_by": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
} Info
Anda tidak dapat mengundang seseorang sebagai owner. Kepemilikan harus ditransfer secara eksplisit oleh owner saat ini.
Perbarui Role Anggota
Mengubah role anggota organisasi yang ada.
PATCH /api/v1/organizations/{id}/members/{user_id}
Content-Type: application/json Request Body
{
"role": "admin"
} Response (200 OK)
{
"user_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"email": "bob@acme.com",
"role": "admin",
"updated_at": "2026-02-20T11:00:00Z"
} Hierarki Role
| Role | Izin |
|---|---|
owner | Kontrol penuh, billing, hapus org, transfer kepemilikan |
admin | Kelola anggota, aplikasi, pengaturan, kebijakan |
member | Akses aplikasi, buat resource dalam aplikasi |
viewer | Akses baca-saja ke aplikasi dan resource |
Hapus Anggota
Menghapus anggota dari organisasi. Akun pengguna tidak dihapus, hanya keanggotaannya.
DELETE /api/v1/organizations/{id}/members/{user_id} Response (200 OK)
{
"user_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"removed_at": "2026-02-20T12:00:00Z"
} Peringatan
Anda tidak dapat menghapus owner organisasi. Transfer kepemilikan terlebih dahulu menggunakan alur transfer kepemilikan terpisah.
Kebijakan Organisasi
Kebijakan memungkinkan organisasi Business+ untuk menerapkan persyaratan keamanan di semua anggota. Ini mengontrol kekuatan password, MFA, perilaku sesi, dan pembatasan IP.
Fitur Business+
Kebijakan organisasi tersedia di paket Business dan Enterprise. Paket Free dan Starter mendapatkan response 403.
Lihat Kebijakan
GET /api/v1/organizations/{id}/policies Response (200 OK)
{
"organization_id": "550e8400-e29b-41d4-a716-446655440000",
"password_policy": {
"min_length": 12,
"require_uppercase": true,
"require_lowercase": true,
"require_numbers": true,
"require_special_chars": true,
"max_age_days": 90,
"prevent_reuse_count": 5
},
"mfa_policy": {
"required": true,
"allowed_methods": ["totp", "webauthn"],
"grace_period_hours": 48
},
"session_policy": {
"max_session_duration_hours": 24,
"idle_timeout_minutes": 30,
"max_concurrent_sessions": 5
},
"ip_allowlist": {
"enabled": false,
"allowed_ips": []
},
"updated_at": "2026-02-15T09:00:00Z"
} Perbarui Kebijakan
Mengganti seluruh konfigurasi kebijakan. Sertakan semua bagian kebijakan dalam request.
PUT /api/v1/organizations/{id}/policies
Content-Type: application/json Request Body
{
"password_policy": {
"min_length": 14,
"require_uppercase": true,
"require_lowercase": true,
"require_numbers": true,
"require_special_chars": true,
"max_age_days": 60,
"prevent_reuse_count": 10
},
"mfa_policy": {
"required": true,
"allowed_methods": ["totp", "webauthn"],
"grace_period_hours": 24
},
"session_policy": {
"max_session_duration_hours": 12,
"idle_timeout_minutes": 15,
"max_concurrent_sessions": 3
},
"ip_allowlist": {
"enabled": true,
"allowed_ips": ["203.0.113.0/24", "198.51.100.42"]
}
} Field Kebijakan
| Bagian | Field | Tipe | Deskripsi |
|---|---|---|---|
password_policy | min_length | int | Panjang minimum password (8-128) |
require_uppercase | boolean | Wajib minimal satu huruf besar | |
require_lowercase | boolean | Wajib minimal satu huruf kecil | |
require_numbers | boolean | Wajib minimal satu digit | |
require_special_chars | boolean | Wajib minimal satu karakter khusus | |
max_age_days | int | Paksa reset password setelah N hari (0 = nonaktif) | |
prevent_reuse_count | int | Jumlah password sebelumnya yang diblokir (0-24) | |
mfa_policy | required | boolean | Wajibkan MFA untuk semua anggota |
allowed_methods | string[] | Metode MFA yang diizinkan: totp, webauthn | |
grace_period_hours | int | Jam sebelum MFA diberlakukan setelah perubahan kebijakan | |
session_policy | max_session_duration_hours | int | Masa hidup sesi absolut (1-720) |
idle_timeout_minutes | int | Timeout tidak aktif (5-1440) | |
max_concurrent_sessions | int | Sesi aktif maksimum per pengguna (1-100) | |
ip_allowlist | enabled | boolean | Aktifkan pembatasan IP |
allowed_ips | string[] | IP atau range CIDR yang diizinkan |
Response (200 OK)
Mengembalikan objek kebijakan yang diperbarui secara lengkap (bentuk sama dengan response GET).
Branding Organisasi
Kustomisasi tampilan dan nuansa halaman autentikasi dan email untuk organisasi Anda (white-label). Tersedia di paket Business+.
Fitur Business+
Kustomisasi branding tersedia di paket Business dan Enterprise.
Lihat Branding
GET /api/v1/organizations/{id}/branding Response (200 OK)
{
"organization_id": "550e8400-e29b-41d4-a716-446655440000",
"logo_url": "https://cdn.arsaka.io/orgs/acme/logo.png",
"favicon_url": "https://cdn.arsaka.io/orgs/acme/favicon.ico",
"primary_color": "#2563EB",
"accent_color": "#7C3AED",
"custom_login": {
"title": "Acme Corp Portal",
"subtitle": "Sign in to your workspace",
"background_url": "https://cdn.arsaka.io/orgs/acme/bg.jpg"
},
"email_branding": {
"from_name": "Acme Corp",
"reply_to": "support@acme.com",
"footer_text": "Acme Corp, 123 Main St, Jakarta"
},
"updated_at": "2026-02-18T16:00:00Z"
} Perbarui Branding
PUT /api/v1/organizations/{id}/branding
Content-Type: application/json Request Body
{
"logo_url": "https://cdn.arsaka.io/orgs/acme/logo-v2.png",
"primary_color": "#1D4ED8",
"accent_color": "#6D28D9",
"custom_login": {
"title": "Welcome to Acme",
"subtitle": "Enterprise workspace login",
"background_url": null
},
"email_branding": {
"from_name": "Acme Corporation",
"reply_to": "noreply@acme.com",
"footer_text": "Acme Corporation, Jakarta, Indonesia"
}
} Field Branding
| Field | Tipe | Deskripsi |
|---|---|---|
logo_url | string | URL logo organisasi (PNG/SVG, maks 2 MB) |
favicon_url | string | URL favicon (ICO/PNG, maks 256 KB) |
primary_color | string | Warna brand utama (hex, contoh #2563EB) |
accent_color | string | Warna brand aksen (hex) |
custom_login.title | string | Judul halaman login |
custom_login.subtitle | string | Subjudul halaman login |
custom_login.background_url | string|null | URL gambar latar halaman login (null untuk menghapus) |
email_branding.from_name | string | Nama tampilan di email keluar |
email_branding.reply_to | string | Alamat email reply-to |
email_branding.footer_text | string | Teks footer di email transaksional |
Response (200 OK)
Mengembalikan objek branding yang diperbarui secara lengkap (bentuk sama dengan response GET).
Konfigurasi SSO
Konfigurasi Single Sign-On berbasis SAML untuk organisasi Anda. Saat SSO diaktifkan, anggota melakukan autentikasi melalui identity provider (IdP) Anda, bukan kredensial PUGUH.
Fitur Business+
SSO tersedia di paket Business dan Enterprise. Mendukung SAML 2.0 dengan IdP yang kompatibel (Okta, Azure AD, Google Workspace, dll.).
Buat Konfigurasi SSO
POST /api/v1/sso/configurations
Content-Type: application/json Request Body
{
"organization_id": "550e8400-e29b-41d4-a716-446655440000",
"provider": "saml",
"idp_entity_id": "https://idp.acme.com/metadata",
"idp_sso_url": "https://idp.acme.com/sso/saml",
"idp_certificate": "-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----",
"domain_whitelist": ["acme.com", "acme.co.id"],
"auto_provision": true,
"default_role": "member"
} Field Request
| Field | Tipe | Wajib | Deskripsi |
|---|---|---|---|
organization_id | uuid | Ya | Organisasi yang akan dikonfigurasi SSO |
provider | string | Ya | Tipe provider SSO: saml |
idp_entity_id | string | Ya | Entity ID Identity Provider (dari metadata IdP) |
idp_sso_url | string | Ya | URL Single Sign-On IdP |
idp_certificate | string | Ya | Sertifikat X.509 IdP (format PEM) |
domain_whitelist | string[] | Tidak | Domain email yang harus menggunakan SSO |
auto_provision | boolean | Tidak | Otomatis buat akun pengguna saat login SSO pertama (default false) |
default_role | string | Tidak | Role untuk pengguna yang otomatis dibuat (default member) |
Response (201 Created)
{
"organization_id": "550e8400-e29b-41d4-a716-446655440000",
"provider": "saml",
"idp_entity_id": "https://idp.acme.com/metadata",
"idp_sso_url": "https://idp.acme.com/sso/saml",
"sp_entity_id": "https://api-puguh.arsaka.io/sso/saml/550e8400",
"sp_acs_url": "https://api-puguh.arsaka.io/sso/saml/550e8400/acs",
"domain_whitelist": ["acme.com", "acme.co.id"],
"auto_provision": true,
"default_role": "member",
"is_active": true,
"created_at": "2026-02-20T10:00:00Z"
} Tip
Setelah membuat konfigurasi SSO, gunakan sp_entity_id dan sp_acs_url yang dikembalikan untuk mengkonfigurasi Service Provider di IdP Anda.
Lihat Konfigurasi SSO
GET /api/v1/sso/configurations/{org_id} Response (200 OK)
{
"organization_id": "550e8400-e29b-41d4-a716-446655440000",
"provider": "saml",
"idp_entity_id": "https://idp.acme.com/metadata",
"idp_sso_url": "https://idp.acme.com/sso/saml",
"sp_entity_id": "https://api-puguh.arsaka.io/sso/saml/550e8400",
"sp_acs_url": "https://api-puguh.arsaka.io/sso/saml/550e8400/acs",
"domain_whitelist": ["acme.com", "acme.co.id"],
"auto_provision": true,
"default_role": "member",
"is_active": true,
"created_at": "2026-02-20T10:00:00Z",
"updated_at": "2026-02-20T10:00:00Z"
} Perbarui Konfigurasi SSO
PUT /api/v1/sso/configurations/{org_id}
Content-Type: application/json Request Body
{
"idp_sso_url": "https://idp.acme.com/sso/saml/v2",
"idp_certificate": "-----BEGIN CERTIFICATE-----\nNEWC...\n-----END CERTIFICATE-----",
"domain_whitelist": ["acme.com"],
"auto_provision": false
} Response (200 OK)
Mengembalikan objek konfigurasi SSO yang diperbarui secara lengkap (bentuk sama dengan response GET).
Response Error
Semua error mengembalikan kode status HTTP yang sesuai dengan body JSON berisi field detail. Tidak ada wrapper {success, error}.
400 Bad Request
Body request atau parameter tidak valid:
{
"detail": "Validation error: name must be between 2 and 100 characters"
} 401 Unauthorized
Autentikasi tidak ada atau tidak valid:
{
"detail": "Invalid or expired token"
} 403 Forbidden
Izin tidak memadai atau pembatasan paket:
{
"detail": "Organization policies require Business plan or higher"
} Atau role tidak memadai:
{
"detail": "Only organization owner or admin can invite members"
} 404 Not Found
Organisasi atau anggota tidak ditemukan:
{
"detail": "Organization not found"
} 409 Conflict
Resource duplikat:
{
"detail": "Organization with slug 'acme-corp' already exists"
} Atau undangan duplikat:
{
"detail": "User bob@acme.com is already a member of this organization"
} 422 Unprocessable Entity
Request tidak valid secara semantik:
{
"detail": "Cannot remove the last owner from the organization"
} 429 Too Many Requests
Rate limit terlampaui:
{
"detail": "Rate limit exceeded. Retry after 60 seconds"
} Terkait
- API Autentikasi — API keys, JWT tokens, dan OAuth
- API Webhooks — Konfigurasi webhook endpoints dan pengiriman event
- Python SDK —
OrganizationClientdengan 17 metode - TypeScript SDK —
OrganizationClientuntuk frontend dan Node.js