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 responsjuglow-workspace-iddan diterima oleh Get Workspace), tetapi tidak muncul dalam hasil List Workspaces, dan kunci API, laporan penggunaan, serta laporan biaya menampilkannulluntukworkspace_id-nya, begitu pula kunci API semua-workspace (fieldscopepada 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.
| Peran | Izin |
|---|---|
| Workspace User | Hanya menggunakan playground |
| Workspace Limited Developer | Membuat dan mengelola kunci API, menggunakan API. Tidak dapat mengakses tampilan pelacakan sesi atau mengunduh file. |
| Workspace Developer | Membuat dan mengelola kunci API, menggunakan API |
| Workspace Admin | Kontrol penuh atas pengaturan dan anggota workspace |
| Workspace Billing | Melihat 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
- Buka pengaturan workspace
Di Haijun Console, buka Settings > Workspaces.
- Buat workspace
Klik Create workspace.
- Konfigurasikan workspace
Masukkan nama workspace dan pilih warna untuk identifikasi visual.
- 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:
- Pilih workspace dari daftar.
- Klik menu elipsis (...) dan pilih Edit details.
- Perbarui nama atau warna dan simpan perubahan Anda.
Note: Default Workspace tidak dapat diubah namanya atau dihapus.
Menambahkan anggota ke workspace
- Buka tab Members pada workspace.
- Klik Add to Workspace.
- Pilih anggota organisasi dan tetapkan peran workspace untuk mereka.
- 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:
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"}' ant beta:organization:workspaces create --name Production client = juglow.Juglow()
workspace = client.beta.organization.workspaces.create(name="Production")
print(f"id: {workspace.id}")
print(f"name: {workspace.name}") const client = new Juglow();
const workspace = await client.beta.organization.workspaces.create({ name: "Production" });
console.log(`id: ${workspace.id}`);
console.log(`name: ${workspace.name}`); JuglowClient client = new();
var workspace = await client.Beta.Organization.Workspaces.Create(new()
{
Name = "Production"
});
Console.WriteLine($"id: {workspace.ID}");
Console.WriteLine($"name: {workspace.Name}"); 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) 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());
} $client = new Client();
$workspace = $client->beta->organization->workspaces->create(
name: 'Production',
);
echo "id: {$workspace->id}\n";
echo "name: {$workspace->name}\n"; client = Juglow::Client.new
workspace = client.beta.organization.workspaces.create(name: "Production")
puts "id: #{workspace.id}"
puts "name: #{workspace.name}"Mendaftar workspace:
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" ant beta:organization:workspaces list --limit 10 --include-archived=false client = juglow.Juglow()
workspaces = client.beta.organization.workspaces.list(limit=10, include_archived=False)
for workspace in workspaces:
print(f"{workspace.id}: {workspace.name}") 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}`);
} 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}");
} 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)
} 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());
}
} $client = new Client();
$workspaces = $client->beta->organization->workspaces->list(
limit: 10,
includeArchived: false,
);
foreach ($workspaces->getItems() as $workspace) {
echo "{$workspace->id}: {$workspace->name}\n";
} 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}"
endMengarsipkan workspace:
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" ant beta:organization:workspaces archive --workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ client = juglow.Juglow()
workspace = client.beta.organization.workspaces.archive(
"wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
)
print(f"id: {workspace.id}")
print(f"archived_at: {workspace.archived_at}") 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}`); 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}"); 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) 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()); $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"; 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:
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"
}' ant beta:organization:workspaces:members add \
--workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ \
--user-id user_01XyDMpzjS89pFZXqSFUBDr6 \
--workspace-role workspace_developer 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}") 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}`); 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()}"); 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) 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());
} 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"; 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:
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"}' ant beta:organization:workspaces:members update \
--user-id user_01XyDMpzjS89pFZXqSFUBDr6 \
--workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ \
--workspace-role workspace_admin 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}") 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}`); 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()}"); 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) 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());
} 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"; 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:
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" ant beta:organization:workspaces:members remove \
--user-id user_01XyDMpzjS89pFZXqSFUBDr6 \
--workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ 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}") 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}`); JuglowClient client = new();
var removedMember = await client.Beta.Organization.Workspaces.Members.Remove(
"user_01XyDMpzjS89pFZXqSFUBDr6",
new() { WorkspaceID = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }
);
Console.WriteLine($"user_id: {removedMember.UserID}"); 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) 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());
} $client = new Client();
$removedMember = $client->beta->organization->workspaces->members->remove(
userID: 'user_01XyDMpzjS89pFZXqSFUBDr6',
workspaceID: 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ',
);
echo "user_id: {$removedMember->userID}\n"; 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-idpada setiap permintaan. Akun harus memiliki akses ke workspace tersebut untuk menggunakannya.
Sumber daya yang dibatasi cakupannya ke workspace meliputi:
- File yang dibuat melalui Files API
- Message Batches yang dibuat melalui Batch API
- Tracks yang dibuat melalui Tracks API
Beberapa sumber daya dikelola secara berbeda:
- MCP tunnel dikelola dengan token OAuth
workspace:manage_tunnelsyang 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/1.1 200 OK
request-id: req_018EeWyXxfu5pfWkrYcMdjWG
juglow-organization-id: 0d0e7a3b-52f1-4c7e-9a51-3f6f2f7c1b9e
juglow-workspace-id: wrkspc_01JwQvzr7rXLA5AGx3HKfFUJHeader 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:
# -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' # --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 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}") 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")); 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}"); 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")) 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);
} $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"; 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}"Workspace ID: wrkspc_01JwQvzr7rXLA5AGx3HKfFUJAccessor 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_iddalam laporan Usage and Cost API dan pada objek Admin API seperti kunci API (keduanya melaporkannulluntuk Default Workspace, seperti halnya kunci API untuk kunci semua-workspace; fieldscopepada 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:
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:
| Workspace | Tujuan |
|---|---|
| Development | Pengujian dan eksperimen dengan batas laju yang lebih rendah |
| Staging | Pengujian pra-produksi dengan batas yang menyerupai produksi |
| Production | Lalu 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
- Rencanakan struktur workspace Anda
Pertimbangkan bagaimana Anda akan mengatur workspace sebelum membuatnya. Pikirkan kebutuhan penagihan, kontrol akses, dan pelacakan penggunaan.
- Gunakan nama yang bermakna
Beri nama workspace dengan jelas untuk menunjukkan tujuannya (misalnya, "Production - Customer Chatbot" atau "Dev - Internal Tools").
- Tetapkan batas yang sesuai
Konfigurasikan batas pengeluaran dan batas laju untuk mencegah biaya tak terduga dan memastikan distribusi sumber daya yang adil.
- Audit akses secara berkala
Tinjau keanggotaan workspace secara berkala untuk memastikan hanya pengguna yang sesuai yang memiliki akses.
- 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.