Haijun Platform Docs
EN

Workspace menyediakan cara untuk mengatur penggunaan API Anda dalam sebuah organisasi. Gunakan workspace untuk memisahkan berbagai proyek, lingkungan, atau tim sambil tetap mempertahankan penagihan dan administrasi yang terpusat.

Cara kerja workspace

Setiap organisasi memiliki Default Workspace yang tidak dapat diubah namanya, diarsipkan, atau dihapus. Saat Anda membuat workspace tambahan, Anda dapat menetapkan anggota, service account, kunci API, dan batas sumber daya untuk masing-masing workspace.

Karakteristik utama:

  • Pengenal workspace menggunakan prefiks wrkspc_ (misalnya, wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ)
  • Maksimum 100 workspace per organisasi secara default (workspace yang diarsipkan tidak dihitung); hubungi tim akun Anda jika Anda membutuhkan lebih banyak
  • Default Workspace memiliki ID wrkspc_ seperti workspace lainnya (dikembalikan dalam header respons juglow-workspace-id dan diterima oleh Get Workspace), tetapi tidak muncul dalam hasil List Workspaces, dan kunci API, laporan penggunaan, serta laporan biaya menampilkan null untuk workspace_id-nya, begitu pula kunci API semua-workspace (field scope pada kunci API membedakan keduanya; untuk kunci yang terikat pada Default Workspace, field tersebut memuat ID yang sebenarnya)
  • Kunci API dapat dibatasi cakupannya ke satu workspace. Dalam hal ini, kunci tersebut hanya dapat mengakses sumber daya di dalam workspace itu. Beberapa kunci API dapat diberi izin di beberapa workspace, dan menyertakan header ID workspace untuk mengakses sumber daya di dalam workspace tersebut

Workspace Haijun Code

Ketika seorang anggota organisasi Anda pertama kali masuk ke Haijun Code dengan akun Haijun Console mereka, Juglow secara otomatis membuat workspace Haijun Code di organisasi tersebut dan menambahkan anggota itu ke dalamnya. Setiap anggota berikutnya yang masuk ke Haijun Code ditambahkan dengan cara yang sama.

Workspace Haijun Code menjaga lalu lintas Haijun Code terpisah dari beban kerja API Anda yang lain:

  • Haijun Code membuat kunci API per pengguna di workspace ini saat masuk. Anda tidak dapat membuat kunci di dalamnya secara manual dari Console.
  • Kunci Haijun Code berhenti berfungsi jika pemiliknya dihapus dari workspace atau organisasi, tidak seperti kunci workspace.
  • Penggunaan Haijun Code dikenai "rate limit" (batas laju) secara terpisah, dan admin dapat membatasi porsinya dari batas organisasi di Settings > Workspaces.
  • Ini adalah satu-satunya workspace yang mendukung batas pengeluaran bulanan per pengguna.

Warning: Mengarsipkan workspace Haijun Code akan menonaktifkan proses masuk Haijun Code melalui penagihan Console untuk seluruh organisasi.

Peran dan izin workspace

Anggota dapat memiliki peran yang berbeda di setiap workspace, sehingga memungkinkan kontrol akses yang terperinci.

PeranIzin
Workspace UserHanya menggunakan playground
Workspace Limited DeveloperMembuat dan mengelola kunci API, menggunakan API. Tidak dapat mengakses tampilan pelacakan sesi atau mengunduh file.
Workspace DeveloperMembuat dan mengelola kunci API, menggunakan API
Workspace AdminKontrol penuh atas pengaturan dan anggota workspace
Workspace BillingMelihat informasi penagihan workspace (diwarisi dari peran billing organisasi)

Pewarisan peran

  • Admin organisasi secara otomatis menerima akses Workspace Admin ke semua workspace
  • Anggota billing organisasi secara otomatis menerima akses Workspace Billing ke semua workspace
  • User dan developer organisasi harus ditambahkan secara eksplisit ke setiap workspace
  • Service account ditambahkan ke workspace dari halaman service account di Settings → Service accounts atau dari tab Service accounts pada workspace

Note: Peran Workspace Billing tidak dapat ditetapkan secara manual. Peran ini diwarisi dari kepemilikan peran billing organisasi.

Mengelola workspace

Note: Hanya admin organisasi yang dapat membuat workspace. User dan developer organisasi harus ditambahkan ke workspace oleh admin.

Menggunakan Console

Buat dan kelola workspace di Haijun Console.

Membuat workspace

  1. Buka pengaturan workspace

Di Haijun Console, buka Settings > Workspaces.

  1. Buat workspace

Klik Create workspace.

  1. Konfigurasikan workspace

Masukkan nama workspace dan pilih warna untuk identifikasi visual.

  1. Buat workspace tersebut

Klik Create untuk menyelesaikan.

Tip: Untuk berpindah antar workspace di Console, gunakan pemilih Workspaces di sudut kiri atas.

Mengedit detail workspace

Untuk mengubah nama atau warna workspace:

  1. Pilih workspace dari daftar.
  1. Klik menu elipsis (...) dan pilih Edit details.
  1. Perbarui nama atau warna dan simpan perubahan Anda.

Note: Default Workspace tidak dapat diubah namanya atau dihapus.

Menambahkan anggota ke workspace

  1. Buka tab Members pada workspace.
  1. Klik Add to Workspace.
  1. Pilih anggota organisasi dan tetapkan peran workspace untuk mereka.
  1. Konfirmasikan penambahan tersebut.

Untuk menghapus anggota, klik ikon tempat sampah di sebelah nama mereka.

Note: Admin organisasi dan anggota billing tidak dapat dihapus dari workspace selama mereka memegang peran organisasi tersebut.

Menetapkan batas workspace

Pengaturan setiap workspace membagi batas-batas ini ke dalam dua tab:

  • Batas laju: Pada tab Rate limits, tetapkan batas per tingkat model untuk permintaan per menit, token input, atau token output
  • Batas pengeluaran: Pada tab Spend limits, batasi pengeluaran bulanan dan konfigurasikan peringatan ketika pengeluaran mencapai ambang tertentu

Mengarsipkan workspace

Untuk mengarsipkan workspace, klik menu elipsis (...) dan pilih Archive. Pengarsipan:

  • Mempertahankan data historis untuk pelaporan
  • Menonaktifkan workspace dan mengarsipkan setiap kunci API yang dibuat untuknya
  • Tidak dapat dibatalkan

Warning: Mengarsipkan workspace akan mengarsipkan setiap kunci API yang dibuat untuk workspace tersebut dalam hitungan detik (kunci-kunci itu tetap tercantum di Admin API sebagai diarsipkan), dan kunci multi-workspace tidak dapat lagi beroperasi di dalamnya. Tindakan ini tidak dapat dibatalkan. Jika Anda mengarsipkan workspace Haijun Code, anggota organisasi Anda tidak dapat lagi masuk ke Haijun Code melalui penagihan Console.

Menggunakan Admin API

Kelola workspace secara terprogram menggunakan Admin API.

Note: Endpoint Admin API menerima kunci Admin API, token OAuth org:admin, atau kunci personal maupun kunci service account yang tidak dibatasi cakupannya ke workspace tertentu. Kunci workspace tidak berfungsi di sana. Lihat Autentikasi.

Contoh SDK dan CLI berikut membuat client default, yang membaca kunci Admin API dari variabel lingkungan JUGLOW_API_KEY; SDK mengekspos endpoint ini di bawah client.beta.organization.workspaces. Metode list pada SDK mengambil halaman berikutnya sesuai permintaan, sehingga limit menetapkan ukuran halaman; contoh PHP, Ruby, dan curl mengembalikan satu halaman.

Membuat workspace:

bash
  curl -X POST "https://haijun.my.id/v1/organizations/workspaces" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{"name": "Production"}'
bash
  ant beta:organization:workspaces create --name Production
python
  client = juglow.Juglow()

  workspace = client.beta.organization.workspaces.create(name="Production")

  print(f"id: {workspace.id}")
  print(f"name: {workspace.name}")
typescript
  const client = new Juglow();

  const workspace = await client.beta.organization.workspaces.create({ name: "Production" });

  console.log(`id: ${workspace.id}`);
  console.log(`name: ${workspace.name}`);
csharp
  JuglowClient client = new();

  var workspace = await client.Beta.Organization.Workspaces.Create(new()
  {
      Name = "Production"
  });

  Console.WriteLine($"id: {workspace.ID}");
  Console.WriteLine($"name: {workspace.Name}");
go
  client := juglow.NewClient()

  workspace, err := client.Beta.Organization.Workspaces.New(context.Background(), juglow.BetaOrganizationWorkspaceNewParams{
  	Name: "Production",
  })
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", workspace.ID)
  fmt.Printf("name: %s\n", workspace.Name)
java
  import com.juglow.models.beta.organization.workspaces.WorkspaceCreateParams;

  void main() {
      JuglowClient client = JuglowOkHttpClient.fromEnv();

      var params = WorkspaceCreateParams.builder()
          .name("Production")
          .build();
      var workspace = client.beta().organization().workspaces().create(params);

      IO.println("id: " + workspace.id());
      IO.println("name: " + workspace.name());
  }
php
  $client = new Client();

  $workspace = $client->beta->organization->workspaces->create(
      name: 'Production',
  );

  echo "id: {$workspace->id}\n";
  echo "name: {$workspace->name}\n";
ruby
  client = Juglow::Client.new

  workspace = client.beta.organization.workspaces.create(name: "Production")

  puts "id: #{workspace.id}"
  puts "name: #{workspace.name}"

Mendaftar workspace:

bash
  curl "https://haijun.my.id/v1/organizations/workspaces?limit=10&include_archived=false" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01"
bash
  ant beta:organization:workspaces list --limit 10 --include-archived=false
python
  client = juglow.Juglow()

  workspaces = client.beta.organization.workspaces.list(limit=10, include_archived=False)

  for workspace in workspaces:
      print(f"{workspace.id}: {workspace.name}")
typescript
  const client = new Juglow();

  const workspaces = await client.beta.organization.workspaces.list({
    limit: 10,
    include_archived: false
  });

  for await (const workspace of workspaces) {
    console.log(`${workspace.id}: ${workspace.name}`);
  }
csharp
  JuglowClient client = new();

  var workspaces = await client.Beta.Organization.Workspaces.List(new()
  {
      Limit = 10,
      IncludeArchived = false
  });

  await foreach (var workspace in workspaces.Paginate())
  {
      Console.WriteLine($"{workspace.ID}: {workspace.Name}");
  }
go
  client := juglow.NewClient()

  workspaces := client.Beta.Organization.Workspaces.ListAutoPaging(context.Background(), juglow.BetaOrganizationWorkspaceListParams{
  	Limit:           juglow.Int(10),
  	IncludeArchived: juglow.Bool(false),
  })

  for workspaces.Next() {
  	workspace := workspaces.Current()
  	fmt.Printf("%s: %s\n", workspace.ID, workspace.Name)
  }
  if err := workspaces.Err(); err != nil {
  	log.Fatal(err)
  }
java
  import com.juglow.models.beta.organization.workspaces.WorkspaceListParams;

  void main() {
      JuglowClient client = JuglowOkHttpClient.fromEnv();

      var params = WorkspaceListParams.builder()
          .limit(10)
          .includeArchived(false)
          .build();
      var workspaces = client.beta().organization().workspaces().list(params);

      for (var workspace : workspaces.autoPager()) {
          IO.println(workspace.id() + ": " + workspace.name());
      }
  }
php
  $client = new Client();

  $workspaces = $client->beta->organization->workspaces->list(
      limit: 10,
      includeArchived: false,
  );

  foreach ($workspaces->getItems() as $workspace) {
      echo "{$workspace->id}: {$workspace->name}\n";
  }
ruby
  client = Juglow::Client.new

  workspaces = client.beta.organization.workspaces.list(limit: 10, include_archived: false)

  workspaces.data.each do |workspace|
    puts "#{workspace.id}: #{workspace.name}"
  end

Mengarsipkan workspace:

bash
  curl -X POST "https://haijun.my.id/v1/organizations/workspaces/wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ/archive" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01"
bash
  ant beta:organization:workspaces archive --workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ
python
  client = juglow.Juglow()

  workspace = client.beta.organization.workspaces.archive(
      "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
  )

  print(f"id: {workspace.id}")
  print(f"archived_at: {workspace.archived_at}")
typescript
  const client = new Juglow();

  const workspace = await client.beta.organization.workspaces.archive(
    "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
  );

  console.log(`id: ${workspace.id}`);
  console.log(`archived_at: ${workspace.archived_at}`);
csharp
  JuglowClient client = new();

  var workspace = await client.Beta.Organization.Workspaces.Archive(
      "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
  );

  Console.WriteLine($"id: {workspace.ID}");
  Console.WriteLine($"archived_at: {workspace.ArchivedAt:O}");
go
  client := juglow.NewClient()

  workspace, err := client.Beta.Organization.Workspaces.Archive(context.Background(), "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ")
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", workspace.ID)
  fmt.Printf("archived_at: %s\n", workspace.ArchivedAt)
java
  JuglowClient client = JuglowOkHttpClient.fromEnv();

  var workspace = client.beta().organization().workspaces()
      .archive("wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ");

  IO.println("id: " + workspace.id());
  IO.println("archived_at: " + workspace.archivedAt().orElseThrow());
php
  $client = new Client();

  $workspace = $client->beta->organization->workspaces->archive(
      workspaceID: 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ',
  );

  echo "id: {$workspace->id}\n";
  echo "archived_at: {$workspace->archivedAt?->format(DATE_ATOM)}\n";
ruby
  client = Juglow::Client.new

  workspace_id = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
  workspace = client.beta.organization.workspaces.archive(workspace_id)

  puts "id: #{workspace.id}"
  puts "archived_at: #{workspace.archived_at}"

Untuk detail parameter lengkap dan skema respons, lihat referensi Workspaces API.

Mengelola anggota workspace

Menambahkan anggota ke workspace:

bash
  curl -X POST "https://haijun.my.id/v1/organizations/workspaces/wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ/members" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "user_id": "user_01XyDMpzjS89pFZXqSFUBDr6",
      "workspace_role": "workspace_developer"
    }'
bash
  ant beta:organization:workspaces:members add \
    --workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ \
    --user-id user_01XyDMpzjS89pFZXqSFUBDr6 \
    --workspace-role workspace_developer
python
  client = juglow.Juglow()

  member = client.beta.organization.workspaces.members.add(
      "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
      user_id="user_01XyDMpzjS89pFZXqSFUBDr6",
      workspace_role="workspace_developer",
  )

  print(f"user_id: {member.user_id}")
  print(f"workspace_role: {member.workspace_role}")
typescript
  const client = new Juglow();

  const member = await client.beta.organization.workspaces.members.add(
    "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
    {
      user_id: "user_01XyDMpzjS89pFZXqSFUBDr6",
      workspace_role: "workspace_developer"
    }
  );

  console.log(`user_id: ${member.user_id}`);
  console.log(`workspace_role: ${member.workspace_role}`);
csharp
  using Juglow.Models.Beta.Organization.Workspaces;

  JuglowClient client = new();

  var member = await client.Beta.Organization.Workspaces.Members.Add(
      "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
      new()
      {
          UserID = "user_01XyDMpzjS89pFZXqSFUBDr6",
          WorkspaceRole = BetaNoBillingWorkspaceRole.WorkspaceDeveloper
      }
  );

  Console.WriteLine($"user_id: {member.UserID}");
  Console.WriteLine($"workspace_role: {member.WorkspaceRole.Raw()}");
go
  client := juglow.NewClient()

  member, err := client.Beta.Organization.Workspaces.Members.Add(
  	context.Background(),
  	"wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
  	juglow.BetaOrganizationWorkspaceMemberAddParams{
  		UserID:        "user_01XyDMpzjS89pFZXqSFUBDr6",
  		WorkspaceRole: juglow.BetaNoBillingWorkspaceRoleWorkspaceDeveloper,
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("user_id: %s\n", member.UserID)
  fmt.Printf("workspace_role: %s\n", member.WorkspaceRole)
java
  import com.juglow.models.beta.organization.workspaces.BetaNoBillingWorkspaceRole;
  import com.juglow.models.beta.organization.workspaces.members.MemberAddParams;

  void main() {
      JuglowClient client = JuglowOkHttpClient.fromEnv();

      var params = MemberAddParams.builder()
          .userId("user_01XyDMpzjS89pFZXqSFUBDr6")
          .workspaceRole(BetaNoBillingWorkspaceRole.WORKSPACE_DEVELOPER)
          .build();
      var member = client.beta().organization().workspaces().members()
          .add("wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ", params);

      IO.println("user_id: " + member.userId());
      IO.println("workspace_role: " + member.workspaceRole().asString());
  }
php
  use Juglow\Beta\Organization\Workspaces\NoBillingWorkspaceRole;
  // ...

  $client = new Client();

  $member = $client->beta->organization->workspaces->members->add(
      workspaceID: 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ',
      userID: 'user_01XyDMpzjS89pFZXqSFUBDr6',
      workspaceRole: NoBillingWorkspaceRole::WORKSPACE_DEVELOPER,
  );

  echo "user_id: {$member->userID}\n";
  echo "workspace_role: {$member->workspaceRole}\n";
ruby
  client = Juglow::Client.new

  workspace_id = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
  member = client.beta.organization.workspaces.members.add(
    workspace_id,
    user_id: "user_01XyDMpzjS89pFZXqSFUBDr6",
    workspace_role: :workspace_developer
  )

  puts "user_id: #{member.user_id}"
  puts "workspace_role: #{member.workspace_role}"

Memperbarui peran anggota:

bash
  curl -X POST "https://haijun.my.id/v1/organizations/workspaces/wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ/members/user_01XyDMpzjS89pFZXqSFUBDr6" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{"workspace_role": "workspace_admin"}'
bash
  ant beta:organization:workspaces:members update \
    --user-id user_01XyDMpzjS89pFZXqSFUBDr6 \
    --workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ \
    --workspace-role workspace_admin
python
  client = juglow.Juglow()

  member = client.beta.organization.workspaces.members.update(
      "user_01XyDMpzjS89pFZXqSFUBDr6",
      workspace_id="wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
      workspace_role="workspace_admin",
  )

  print(f"user_id: {member.user_id}")
  print(f"workspace_role: {member.workspace_role}")
typescript
  const client = new Juglow();

  const member = await client.beta.organization.workspaces.members.update(
    "user_01XyDMpzjS89pFZXqSFUBDr6",
    {
      workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
      workspace_role: "workspace_admin"
    }
  );

  console.log(`user_id: ${member.user_id}`);
  console.log(`workspace_role: ${member.workspace_role}`);
csharp
  using Juglow.Models.Beta.Organization.Workspaces;

  JuglowClient client = new();

  var member = await client.Beta.Organization.Workspaces.Members.Update(
      "user_01XyDMpzjS89pFZXqSFUBDr6",
      new()
      {
          WorkspaceID = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
          WorkspaceRole = BetaWorkspaceRole.WorkspaceAdmin
      }
  );

  Console.WriteLine($"user_id: {member.UserID}");
  Console.WriteLine($"workspace_role: {member.WorkspaceRole.Raw()}");
go
  client := juglow.NewClient()

  member, err := client.Beta.Organization.Workspaces.Members.Update(
  	context.Background(),
  	"user_01XyDMpzjS89pFZXqSFUBDr6",
  	juglow.BetaOrganizationWorkspaceMemberUpdateParams{
  		WorkspaceID:   "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
  		WorkspaceRole: juglow.BetaWorkspaceRoleWorkspaceAdmin,
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("user_id: %s\n", member.UserID)
  fmt.Printf("workspace_role: %s\n", member.WorkspaceRole)
java
  import com.juglow.models.beta.organization.workspaces.BetaWorkspaceRole;
  import com.juglow.models.beta.organization.workspaces.members.MemberUpdateParams;

  void main() {
      JuglowClient client = JuglowOkHttpClient.fromEnv();

      var params = MemberUpdateParams.builder()
          .workspaceId("wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ")
          .workspaceRole(BetaWorkspaceRole.WORKSPACE_ADMIN)
          .build();
      var member = client.beta().organization().workspaces().members()
          .update("user_01XyDMpzjS89pFZXqSFUBDr6", params);

      IO.println("user_id: " + member.userId());
      IO.println("workspace_role: " + member.workspaceRole().asString());
  }
php
  use Juglow\Beta\Organization\Workspaces\WorkspaceRole;
  // ...

  $client = new Client();

  $member = $client->beta->organization->workspaces->members->update(
      userID: 'user_01XyDMpzjS89pFZXqSFUBDr6',
      workspaceID: 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ',
      workspaceRole: WorkspaceRole::WORKSPACE_ADMIN,
  );

  echo "user_id: {$member->userID}\n";
  echo "workspace_role: {$member->workspaceRole}\n";
ruby
  client = Juglow::Client.new

  user_id = "user_01XyDMpzjS89pFZXqSFUBDr6"
  member = client.beta.organization.workspaces.members.update(
    user_id,
    workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
    workspace_role: :workspace_admin
  )

  puts "user_id: #{member.user_id}"
  puts "workspace_role: #{member.workspace_role}"

Menghapus anggota dari workspace:

bash
  curl -X DELETE "https://haijun.my.id/v1/organizations/workspaces/wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ/members/user_01XyDMpzjS89pFZXqSFUBDr6" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01"
bash
  ant beta:organization:workspaces:members remove \
    --user-id user_01XyDMpzjS89pFZXqSFUBDr6 \
    --workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ
python
  client = juglow.Juglow()

  removed_member = client.beta.organization.workspaces.members.remove(
      "user_01XyDMpzjS89pFZXqSFUBDr6",
      workspace_id="wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
  )

  print(f"user_id: {removed_member.user_id}")
typescript
  const client = new Juglow();

  const removedMember = await client.beta.organization.workspaces.members.remove(
    "user_01XyDMpzjS89pFZXqSFUBDr6",
    { workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }
  );

  console.log(`user_id: ${removedMember.user_id}`);
csharp
  JuglowClient client = new();

  var removedMember = await client.Beta.Organization.Workspaces.Members.Remove(
      "user_01XyDMpzjS89pFZXqSFUBDr6",
      new() { WorkspaceID = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }
  );

  Console.WriteLine($"user_id: {removedMember.UserID}");
go
  client := juglow.NewClient()

  removedMember, err := client.Beta.Organization.Workspaces.Members.Remove(
  	context.Background(),
  	"user_01XyDMpzjS89pFZXqSFUBDr6",
  	juglow.BetaOrganizationWorkspaceMemberRemoveParams{
  		WorkspaceID: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("user_id: %s\n", removedMember.UserID)
java
  import com.juglow.models.beta.organization.workspaces.members.MemberRemoveParams;

  void main() {
      JuglowClient client = JuglowOkHttpClient.fromEnv();

      var params = MemberRemoveParams.builder()
          .workspaceId("wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ")
          .build();
      var removedMember = client.beta().organization().workspaces().members()
          .remove("user_01XyDMpzjS89pFZXqSFUBDr6", params);

      IO.println("user_id: " + removedMember.userId());
  }
php
  $client = new Client();

  $removedMember = $client->beta->organization->workspaces->members->remove(
      userID: 'user_01XyDMpzjS89pFZXqSFUBDr6',
      workspaceID: 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ',
  );

  echo "user_id: {$removedMember->userID}\n";
ruby
  client = Juglow::Client.new

  user_id = "user_01XyDMpzjS89pFZXqSFUBDr6"
  removed_member = client.beta.organization.workspaces.members.remove(
    user_id,
    workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
  )

  puts "user_id: #{removed_member.user_id}"

Untuk detail parameter lengkap, lihat referensi Workspace Members API.

Kunci API dan cakupan sumber daya

Setiap permintaan berjalan di tepat satu workspace dan hanya dapat mengakses sumber daya di dalam workspace tersebut. Workspace mana yang digunakan bergantung pada jenis kunci:

  • Kunci workspace (kunci lama tanpa pemilik) milik workspace tempat kunci itu dibuat dan selalu berjalan di sana.
  • Kunci personal atau kunci service account bertindak sebagai pengguna atau service account-nya. Kunci satu-workspace selalu berjalan di workspace yang dipilih saat kunci itu dibuat. Kunci multi-workspace berjalan di workspace yang disebutkan oleh header juglow-workspace-id pada setiap permintaan. Akun harus memiliki akses ke workspace tersebut untuk menggunakannya.

Sumber daya yang dibatasi cakupannya ke workspace meliputi:

  • Message Batches yang dibuat melalui Batch API

Beberapa sumber daya dikelola secara berbeda:

  • MCP tunnel dikelola dengan token OAuth workspace:manage_tunnels yang diperoleh melalui Workload Identity Federation, bukan kunci API. Tunnel dibuat di dalam sebuah workspace, dan daftar MCP tunnels di Console serta pemilih server Managed Agent hanya menampilkan tunnel di workspace saat ini; batas 10 tunnel aktif berlaku untuk seluruh organisasi. Pengelolaan tunnel memerlukan peran dengan izin pengelolaan tunnel; developer organisasi dapat melihat tetapi tidak dapat mengubahnya.
  • Workspace itu sendiri dan anggota organisasi dikelola di tingkat organisasi melalui Admin API, menggunakan kunci Admin API, token OAuth org:admin, atau kunci personal maupun kunci service account yang tidak dibatasi cakupannya ke workspace tertentu.

Untuk mencari ID workspace organisasi Anda, panggil endpoint List Workspaces atau temukan di Haijun Console.

Note: Cache prompt juga diisolasi per workspace pada Haijun API, Haijun Platform on AWS, dan Microsoft Foundry. Pada Amazon Bedrock dan Google Cloud, cache prompt diisolasi per organisasi.

Mengidentifikasi workspace di balik respons API

Respons Haijun API menyertakan header juglow-workspace-id bersama dengan header respons request-id dan juglow-organization-id. Nilainya adalah ID berprefiks wrkspc_ dari workspace yang menjadi tujuan resolusi kunci API atau access token permintaan tersebut, termasuk ketika workspace itu adalah Default Workspace. Misalnya, respons yang berhasil menyertakan header seperti ini:

http
HTTP/1.1 200 OK
request-id: req_018EeWyXxfu5pfWkrYcMdjWG
juglow-organization-id: 0d0e7a3b-52f1-4c7e-9a51-3f6f2f7c1b9e
juglow-workspace-id: wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ

Header ini tidak ada ketika kredensial tidak teresolusi ke sebuah workspace (misalnya, pada permintaan Admin API) atau ketika permintaan gagal sebelum autentikasi selesai, seperti error 401.

Contoh berikut mengirim permintaan Messages API dan mencetak ID workspace dari header respons:

bash
  # -D - mencetak header respons; -o /dev/null membuang body
  curl -sS -D - -o /dev/null https://haijun.my.id/v1/messages \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "haijun-opus-5-5",
      "max_tokens": 1024,
      "messages": [{"role": "user", "content": "Hello, Haijun"}]
    }' | grep -i '^juglow-workspace-id'
bash
  # --debug mencetak respons HTTP, termasuk Juglow-Workspace-Id
  # header, ke stderr; > /dev/null menyembunyikan body JSON di stdout
  ant --debug messages create \
    --model haijun-opus-5-5 \
    --max-tokens 1024 \
    --message '{role: user, content: "Hello, Haijun"}' > /dev/null
python
  client = juglow.Juglow()

  response = client.messages.with_raw_response.create(
      model="haijun-opus-5-5",
      max_tokens=1024,
      messages=[{"role": "user", "content": "Hello, Haijun"}],
  )
  workspace_id = response.headers.get("juglow-workspace-id")
  print(f"Workspace ID: {workspace_id}")
typescript
  const client = new Juglow();

  const { response } = await client.messages
    .create({
      model: "haijun-opus-5-5",
      max_tokens: 1024,
      messages: [{ role: "user", content: "Hello, Haijun" }]
    })
    .withResponse();
  console.log("Workspace ID:", response.headers.get("juglow-workspace-id"));
csharp
  JuglowClient client = new();

  using var response = await client.WithRawResponse.Messages.Create(new()
  {
      Model = Model.HaijunOpus5_5,
      MaxTokens = 1024,
      Messages = [new() { Role = Role.User, Content = "Hello, Haijun" }]
  });
  var workspaceId = response.GetHeaderValues("juglow-workspace-id").First();
  Console.WriteLine($"Workspace ID: {workspaceId}");
go
  client := juglow.NewClient()

  var response *http.Response
  _, err := client.Messages.New(
  	context.Background(),
  	juglow.MessageNewParams{
  		Model:     juglow.ModelHaijunOpus5_5,
  		MaxTokens: 1024,
  		Messages: []juglow.MessageParam{
  			juglow.NewUserMessage(juglow.NewTextBlock("Hello, Haijun")),
  		},
  	},
  	option.WithResponseInto(&response),
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Println("Workspace ID:", response.Header.Get("juglow-workspace-id"))
java
  import com.juglow.client.JuglowClient;
  import com.juglow.client.okhttp.JuglowOkHttpClient;
  import com.juglow.core.http.HttpResponseFor;
  import com.juglow.models.messages.Message;
  import com.juglow.models.messages.MessageCreateParams;
  import com.juglow.models.messages.Model;

  void main() {
      JuglowClient client = JuglowOkHttpClient.fromEnv();

      HttpResponseFor<Message> response = client.messages().withRawResponse().create(
          MessageCreateParams.builder()
              .model(Model.HAIJUN_OPUS_5_5)
              .maxTokens(1024)
              .addUserMessage("Hello, Haijun")
              .build()
      );

      String workspaceId = response.headers().values("juglow-workspace-id").getFirst();
      IO.println("Workspace ID: " + workspaceId);
  }
php
  $client = new Client();

  $response = $client->messages->raw->create([
      'model' => Model::HAIJUN_OPUS_5_5,
      'maxTokens' => 1024,
      'messages' => [['role' => 'user', 'content' => 'Hello, Haijun']],
  ]);
  echo 'Workspace ID: ' . $response->getHeaderLine('juglow-workspace-id') . "\n";
ruby
  client = Juglow::Client.new

  # Baca header respons di middleware per-permintaan, yang menerima
  # respons HTTP mentah sebelum SDK mem-parsing-nya
  workspace_id = nil
  read_workspace_id = lambda do |request, call_next|
    response = call_next.call(request)
    # Kunci di response.headers menggunakan huruf kecil
    workspace_id = response.headers["juglow-workspace-id"]
    response
  end

  client.messages.create(
    model: Juglow::Model::HAIJUN_OPUS_5_5,
    max_tokens: 1024,
    messages: [{ role: "user", content: "Hello, Haijun" }],
    request_options: { middleware: [read_workspace_id] }
  )
  puts "Workspace ID: #{workspace_id}"
text
Workspace ID: wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ

Accessor yang sama juga membaca header ini dari endpoint Haijun API lainnya, termasuk API Haijun Managed Agents. Misalnya, baca juglow-workspace-id dari respons yang membuat sesi untuk mencatat workspace mana yang memiliki sesi tersebut.

Dengan ID workspace dari sebuah respons, Anda dapat:

  • Mengonfirmasi penggunaan, biaya, dan batas laju workspace mana yang diperhitungkan untuk permintaan tersebut
  • Mencocokkannya dengan field workspace_id dalam laporan Usage and Cost API dan pada objek Admin API seperti kunci API (keduanya melaporkan null untuk Default Workspace, seperti halnya kunci API untuk kunci semua-workspace; field scope pada kunci API membedakan keduanya dan, untuk kunci yang terikat pada satu workspace, memuat ID sebenarnya dari workspace tersebut)
  • Memeriksa apakah itu ID Default Workspace Anda dengan meneruskannya ke Get Workspace menggunakan kunci Admin API: Default Workspace dikembalikan dengan "name": "Default", meskipun List Workspaces tidak menyertakannya
  • Membuka workspace tersebut di Console untuk menemukan sumber daya permintaan itu, seperti sesi, file, message batch, dan track

Batas workspace

Anda dapat menetapkan batas pengeluaran dan batas laju khusus untuk setiap workspace guna melindungi dari penggunaan berlebih dan memastikan distribusi sumber daya yang adil.

Menetapkan batas workspace

Anda dapat menetapkan batas workspace lebih rendah dari (tetapi tidak lebih tinggi dari) batas organisasi Anda:

  • Batas pengeluaran: Batasi pengeluaran bulanan untuk sebuah workspace. Tetapkan ini pada tab pengaturan Spend limits workspace di Haijun Console.
  • Batas laju: Batasi permintaan per menit, token input per menit, atau token output per menit. Tetapkan ini pada tab pengaturan Rate limits workspace di Haijun Console.

Note: - Anda tidak dapat menetapkan batas pada Default Workspace - Jika tidak ditetapkan, batas workspace sama dengan batas organisasi - Batas seluruh organisasi selalu berlaku, meskipun jumlah batas workspace lebih besar

Untuk informasi terperinci tentang batas laju dan cara kerjanya, lihat Batas laju. Anda juga dapat membaca batas laju organisasi dan workspace Anda saat ini secara terprogram dengan Rate Limits API.

Pelacakan penggunaan dan biaya

Lacak penggunaan dan biaya per workspace menggunakan Usage and Cost API:

bash
curl "https://haijun.my.id/v1/organizations/usage_report/messages?\
starting_at=2025-01-01T00:00:00Z&\
ending_at=2025-01-08T00:00:00Z&\
workspace_ids[]=wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ&\
group_by[]=workspace_id&\
bucket_width=1d" \
  -H "juglow-version: 2023-06-01" \
  -H "x-api-key: $JUGLOW_ADMIN_KEY"

Penggunaan dan biaya yang diatribusikan ke Default Workspace memiliki nilai null untuk workspace_id.

Kasus penggunaan umum

Pemisahan lingkungan

Buat workspace terpisah untuk development, staging, dan production:

WorkspaceTujuan
DevelopmentPengujian dan eksperimen dengan batas laju yang lebih rendah
StagingPengujian pra-produksi dengan batas yang menyerupai produksi
ProductionLalu lintas langsung dengan batas laju penuh dan pemantauan

Isolasi tim atau departemen

Tetapkan workspace ke tim yang berbeda untuk alokasi biaya dan kontrol akses:

  • Tim engineering dengan akses developer
  • Tim data science dengan kunci API mereka sendiri
  • Tim support dengan akses terbatas untuk alat pelanggan

Pengaturan berbasis proyek

Buat workspace untuk proyek atau produk tertentu guna melacak penggunaan dan biaya secara terpisah.

Praktik terbaik

  1. Rencanakan struktur workspace Anda

Pertimbangkan bagaimana Anda akan mengatur workspace sebelum membuatnya. Pikirkan kebutuhan penagihan, kontrol akses, dan pelacakan penggunaan.

  1. Gunakan nama yang bermakna

Beri nama workspace dengan jelas untuk menunjukkan tujuannya (misalnya, "Production - Customer Chatbot" atau "Dev - Internal Tools").

  1. Tetapkan batas yang sesuai

Konfigurasikan batas pengeluaran dan batas laju untuk mencegah biaya tak terduga dan memastikan distribusi sumber daya yang adil.

  1. Audit akses secara berkala

Tinjau keanggotaan workspace secara berkala untuk memastikan hanya pengguna yang sesuai yang memiliki akses.

  1. Pantau penggunaan

Gunakan Usage and Cost API untuk melacak konsumsi di tingkat workspace.

FAQ

#### Apa itu Default Workspace?

Setiap organisasi memiliki "Default Workspace" yang tidak dapat diubah namanya, diarsipkan, atau dihapus. Seperti setiap workspace, ia memiliki ID wrkspc_: API mengembalikannya dalam header respons juglow-workspace-id, dan Anda dapat meneruskannya ke Get Workspace dan Update Workspace. Ia tidak memiliki daftar anggota sendiri, karena akses ke dalamnya mengikuti peran organisasi setiap anggota. Ia tidak muncul dalam hasil List Workspaces, dan kunci API, laporan penggunaan, serta laporan biaya yang menjadi miliknya menampilkan null untuk workspace_id, begitu pula kunci API semua-workspace; field scope pada kunci API membedakan keduanya dan, untuk kunci yang menjadi milik Default Workspace, memuat ID sebenarnya.

#### Apa itu workspace Haijun Code?

Juglow membuat workspace Haijun Code secara otomatis saat pertama kali seorang anggota organisasi Anda masuk ke Haijun Code dengan akun Console mereka. Workspace ini mengisolasi kunci API, penggunaan, dan batas laju Haijun Code dari beban kerja Anda yang lain. Lihat Workspace Haijun Code untuk detailnya.

#### Apakah ada batasan pada workspace?

Ya. Setiap organisasi dapat memiliki hingga 100 workspace secara default, dan workspace yang diarsipkan tidak dihitung terhadap batas ini. Jika Anda membutuhkan lebih banyak, hubungi tim akun Anda.

#### Bagaimana peran organisasi memengaruhi akses workspace?

Admin organisasi secara otomatis mendapatkan peran Workspace Admin di semua workspace. Anggota billing organisasi secara otomatis mendapatkan peran Workspace Billing. User dan developer organisasi harus ditambahkan secara manual ke setiap workspace.

#### Peran apa saja yang dapat ditetapkan di workspace?

User dan developer organisasi dapat diberi peran Workspace Admin, Workspace Developer, Workspace Limited Developer, atau Workspace User. Peran Workspace Billing tidak dapat ditetapkan secara manual; peran ini diwarisi dari kepemilikan peran billing organisasi.

#### Dapatkah peran workspace admin organisasi atau anggota billing diubah?

Admin organisasi dan anggota billing tidak dapat diubah peran workspace-nya atau dihapus dari workspace selama mereka memegang peran organisasi tersebut (dengan satu pengecualian: anggota billing dapat ditingkatkan ke peran Workspace Admin). Untuk semua orang lain yang tercakup oleh batasan ini, ubah peran organisasi mereka terlebih dahulu untuk mengubah akses workspace mereka.

#### Apa yang terjadi pada akses workspace ketika peran organisasi berubah?

Jika admin organisasi atau anggota billing diturunkan menjadi user atau developer, mereka kehilangan akses ke semua workspace kecuali workspace tempat mereka ditetapkan perannya secara manual. Ketika pengguna dipromosikan ke peran admin atau billing, mereka mendapatkan akses otomatis ke semua workspace.

#### Apa yang terjadi pada kunci API ketika pengguna dihapus dari workspace?

Perilakunya bergantung pada jenis kunci.

Kunci personal atau kunci service account berhenti berfungsi di sebuah workspace tak lama setelah pengguna atau service account-nya dihapus dari workspace tersebut. Kunci service account tetap berfungsi meskipun pengguna yang membuatnya dihapus. Kunci API workspace tetap berfungsi. Di workspace Haijun Code, setiap kunci terikat pada anggota yang membuatnya dan berhenti berfungsi ketika anggota tersebut dihapus.

Kunci personal diarsipkan ketika penggunanya dihapus dari organisasi. Jika pengguna tersebut diundang kembali, mereka perlu membuat kunci baru; kunci yang diarsipkan tidak dipulihkan.

Lihat juga

On this page
Cara kerja workspaceWorkspace Haijun CodePeran dan izin workspacePewarisan peranMengelola workspaceMenggunakan ConsoleMembuat workspaceMengedit detail workspaceMenambahkan anggota ke workspaceMenetapkan batas workspaceMengarsipkan workspaceMenggunakan Admin APIMengelola anggota workspaceKunci API dan cakupan sumber dayaMengidentifikasi workspace di balik respons APIBatas workspaceMenetapkan batas workspacePelacakan penggunaan dan biayaKasus penggunaan umumPemisahan lingkunganIsolasi tim atau departemenPengaturan berbasis proyekPraktik terbaikFAQLihat juga