# 프로그램 기반 사용자 액세스 제어 관리

이 가이드는 Hub API를 통해 조직 멤버 역할 및 리소스 그룹 멤버십을 관리하는 방법을 설명합니다: 멤버의 조직 역할 및 리소스 그룹 할당 변경, 리소스 그룹 목록 조회, 그룹에 사용자 추가, 배치 워크플로.

**목차:**

- [API를 통해 멤버 역할 변경](#change-member-role-via-api) — 멤버의 조직 역할 및 리소스 그룹 할당을 설정합니다(요청당 1명의 멤버).
- [Resource Groups API](#resource-groups-api) — 리소스 그룹을 나열하고 해당 그룹에 사용자를 추가합니다.
- [API를 통해 자동 가입 구성](#configure-auto-join-via-api) — Resource Group에서 자동 가입을 활성화하거나 비활성화합니다.
- [API를 통해 외부 협업자 초대](#invite-external-collaborators-via-api) — 조직 외부의 사용자를 Resource Group에 초대합니다.
- [API를 통해 멤버 계정 유형 변경](#change-member-account-type-via-api) — 멤버를 외부 협업자로 전환하거나, 다시 원래 상태로 되돌립니다.

---

## API를 통해 멤버 역할 변경

Hub API를 사용하여 멤버의 **조직 역할**(No Access / Read / Contributor / Write / Admin)을 변경하고, 선택적으로 **리소스 그룹**에서의 역할을 변경할 수 있습니다. API는 **요청당 한 명의 멤버**만 업데이트합니다. 여러 멤버의 역할을 변경하려면 루프에서 API를 호출하세요(아래 예시 참조).

**OpenAPI 참조:** PUT /api/organizations/&#123;name&#125;/members/&#123;username&#125;/role

### 필수 조건

- 조직에는 **구독 플랜**(예: Team 또는 Enterprise)이 있어야 합니다. 그렇지 않으면 엔드포인트는 402를 반환합니다.
- 조직에 **Write**(또는 Admin) 권한이 있는 조직 멤버로 인증되어 있어야 합니다.
- 대상 사용자는 이미 조직의 **멤버**여야 합니다.

### Base URL 및 인증

- **기본 URL:** `https://huggingface.co`
- **인증:** 요청 헤더에 토큰을 보내세요:
  ```http
  Authorization: Bearer <your_access_token>
  ```
  [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens)에서 조직에 범위를 지정하고 "Write access to organizations settings / member management" 권한을 가진 세밀한 토큰을 생성하세요.

### 멤버 역할 변경 엔드포인트

**요청**

```http
PUT /api/organizations/{org_name}/members/{username}/role
Authorization: Bearer <your_access_token>
Content-Type: application/json

{
  "role": "read",
  "resourceGroups": []
}
```

- **경로 매개변수**
  - `org_name`: 조직 슬러그(예: `my-org`).
  - `username`: 역할을 변경하려는 멤버의 Hugging Face **username**.
- **본문**
  - `role` (필수): 멤버의 **조직 수준** 역할. 다음 중 하나입니다: `"no_access"`, `"read"`, `"contributor"`, `"write"`, 또는 `"admin"`.
  - `resourceGroups` (선택 사항): 이 사용자의 리소스 그룹 할당 배열입니다. 각 항목:
    - `id`: 리소스 그룹 ID (24자 16진 문자열; [리소스 그룹 목록 API](#list-resource-groups)에서 ID를 가져옵니다).
    - `role`: 해당 리소스 그룹에서의 역할: `"read"`, `"contributor"`, `"write"`, `"admin"` 또는 `"inherit"`.
  - `resourceGroups`를 생략하거나 `[]`를 전달하면 사용자는 모든 리소스 그룹에서 제거됩니다. 조직 역할만 변경하고 리소스 그룹은 변경하지 않으려면 현재 리소스 그룹 멤버십을 전달해야 합니다(본문은 항상 조직 역할과 리소스 그룹 목록을 모두 설정합니다).

**예시 (curl) – 조직 역할을 "read"로 설정, 리소스 그룹 없음(사용자가 이전에 속해 있던 모든 리소스 그룹에서 제거)**

```bash
curl -s -X PUT \
  -H "Authorization: Bearer $HF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role":"read","resourceGroups":[]}' \
  "https://huggingface.co/api/organizations/my-org/members/member1/role"
```

**예시 (curl) – 조직 역할 및 리소스 그룹 역할 설정 (현재 그룹을 덮어씀)**

```bash
curl -s -X PUT \
  -H "Authorization: Bearer $HF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role":"write","resourceGroups":[{"id":"507f1f77bcf86cd799439011","role":"read"}]}' \
  "https://huggingface.co/api/organizations/my-org/members/member2/role"
```

**성공 응답:** 상태 `200 OK`; 본문: `{ "success": true }`.

**일반적인 오류**

- `400` — 잘못된 본문 (예: 잘못된 role 또는 resource group `id`).
- `402` — 조직에 구독 플랜이 없습니다.
- `403` — 허용되지 않음 (예: 조직에 Write 권한이 없거나, 리소스 그룹이 조직에 속하지 않는 경우).
- `404` — 조직 또는 사용자를 찾을 수 없습니다.

### 여러 멤버 업데이트

API는 **요청당 한 명의 멤버**만 변경합니다. 일괄 처리용 엔드포인트는 없습니다. 여러 명의 멤버를 업데이트하려면 사용자 이름별로(예: 목록이나 CSV에서) 엔드포인트를 각각 호출하세요.

**예시: Bash – 사용자 이름 반복, 모든 사용자에게 동일한 역할**

```bash
ORG_NAME="my-org"
ROLE="read"
for username in member1 member2 member3 member4; do
  echo "Setting $username to $ROLE ..."
  curl -s -w "\n%{http_code}" -X PUT \
    -H "Authorization: Bearer $HF_TOKEN" \
    -H "Content-Type: application/json" \
    -d "{\"role\":\"$ROLE\",\"resourceGroups\":[]}" \
    "https://huggingface.co/api/organizations/$ORG_NAME/members/$username/role"
  echo ""
done
```

**예시: Python – 사용자 이름 반복**

```python
import os
import requests

BASE_URL = "https://huggingface.co"
HF_TOKEN = os.environ.get("HF_TOKEN", "")

def change_member_role(org_name: str, username: str, role: str, resource_groups: list | None = None):
    payload = {"role": role, "resourceGroups": resource_groups or []}
    r = requests.put(
        f"{BASE_URL}/api/organizations/{org_name}/members/{username}/role",
        headers={"Authorization": f"Bearer {HF_TOKEN}", "Content-Type": "application/json"},
        json=payload,
    )
    if r.status_code != 200:
        raise RuntimeError(f"{r.status_code}: {r.text}")
    return r.json()

org_name = "my-org"
role = "read"
for username in ["member1", "member2", "member3", "member4"]:
    print(f"Setting {username} to {role} ... ", end="")
    try:
        change_member_role(org_name, username, role)
        print("OK")
    except Exception as e:
        print(f"Failed: {e}")
```

사용자별 역할이 다른 경우, `(username, role)` 쌍(예: CSV에서 가져온 값)을 반복하며 각 쌍에 대해 `change_member_role`을 호출합니다.

---

## Resource Groups API

다음 엔드포인트를 사용하면 리소스 그룹을 **목록으로 표시**하고 해당 그룹에 **사용자를 추가**할 수 있습니다. 기존 멤버의 조직 수준 역할 또는 리소스 그룹 할당을 **변경**하려면 위의 [API를 통한 멤버 역할 변경](#change-member-role-via-api)을 참조하세요.

**OpenAPI 참조:** [리소스 그룹](https://huggingface.co/spaces/huggingface/openapi#tag/resource-groups)

**목차 — API 접근 방식:**

| 목표                                               | 섹션                                                                 |
| -------------------------------------------------- | ----------------------------------------------------------------------- |
| Add many users to **one** resource group           | [리소스 그룹에 사용자 추가](#add-users-to-a-resource-group)         |
| 여러 **리소스 그룹**에 **동일한** 사용자들을 추가 | [API를 반복하여 일괄 추가](#batch-add-by-looping-over-the-api) |
| 그룹별로 **다른** 사용자 추가                  | [API를 반복하여 일괄 추가](#batch-add-by-looping-over-the-api) |

### Base URL 및 인증

- **기본 URL:** `https://huggingface.co`
- **인증:** 다음 중 하나를 사용하세요:
  - **액세스 토큰(스크립트 사용 권장):** [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens)에서 조직 범위로 "Write access to organizations settings / member management" 권한이 설정된 fine-grained 토큰을 생성하세요. 요청 헤더에 토큰을 보내세요:
    ```http
    Authorization: Bearer <your_access_token>
    ```
  - **세션 쿠키:** Hub UI와 동일한 세션을 공유하는 브라우저나 도구에서 호출하는 경우, 쿠키가 자동으로 전송됩니다.

### 리소스 그룹 나열

조직에서 관리할 수 있는 모든 리소스 그룹을 가져옵니다. 이 결과를 사용하여 add-users 호출에서 각 그룹의 `id`를 가져옵니다.

**요청**

```http
GET /api/organizations/{org_name}/resource-groups
Authorization: Bearer <your_access_token>
```

**예시 (curl)**

```bash
curl -s -H "Authorization: Bearer $HF_TOKEN" \
  "https://huggingface.co/api/organizations/my-org/resource-groups"
```

**응답 예시 (단축됨)**

```json
[
  {
    "id": "507f1f77bcf86cd799439011",
    "name": "Cohort 2024",
    "description": "Members in this group",
    "users": [...],
    "repos": [...]
  }
]
```

사용자를 추가할 때 각 리소스 그룹의 `id`를 사용하세요.

### 리소스 그룹에 사용자 추가

…

**요청**

```http
POST /api/organizations/{org_name}/resource-groups/{resource_group_id}/users
Authorization: Bearer <your_access_token>
Content-Type: application/json

{
  "users": [
    { "user": "member1", "role": "read" },
    { "user": "member2", "role": "read" },
    { "user": "member3", "role": "write" }
  ]
}
```

- **경로 매개변수**
  - `org_name`: 조직 슬러그(예: `my-org`).
  - `resource_group_id`: 리소스 그룹의 `id` (목록 엔드포인트에서 가져온 24자 16진 문자열).
- **본문**
  - `users`: 객체 배열. 각 객체는 다음을 가져야 합니다:
    - `user`: Hugging Face **사용자 이름** (필수).
    - `role`: `"read"`, `"contributor"`, `"write"`, `"admin"`, `"inherit"` 중 하나.

**예시 (curl)**

```bash
curl -s -X POST \
  -H "Authorization: Bearer $HF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"users":[{"user":"member1","role":"read"},{"user":"member2","role":"read"}]}' \
  "https://huggingface.co/api/organizations/my-org/resource-groups/507f1f77bcf86cd799439011/users"
```

**성공:** 상태 `200 OK`; 본문은 업데이트된 리소스 그룹 객체입니다(`users`에 새 사용자가 포함됨).

**일반적인 오류:**

- `400` — 예: 사용자가 없음, 중복된 사용자 이름, 잘못된 본문.
- `403` — 허용되지 않음(예: 조직에 속하지 않음 또는 이미 리소스 그룹에 속함). 메시지에 사용자가 조직에 속하지 않는지, 아니면 이미 그룹에 속하는지 표시됩니다.

### 이메일을 통한 멤버 추가 (우회 방법)

add-users 엔드포인트는 이메일이 아닌 **Hugging Face 사용자 이름**만 허용합니다. **이메일** 목록(예: 멤버 이메일)이 있는 경우, 먼저 이메일 → 사용자 이름으로 변환한 다음 add-users API를 호출할 수 있습니다.

이메일 필터링은 이메일의 도메인이 조직의 허용 도메인 중 하나와 일치할 때만 **작동**합니다. 허용 도메인은 **Organization email domain**(Settings → Account → Organization email domain) 및/또는 SSO가 구성된 경우 조직의 **SSO allowed domains**입니다.

**1단계 – 이메일을 사용자 이름으로 해결**

```http
GET /api/organizations/{org_name}/members?email={email}&limit=1
Authorization: Bearer <your_access_token>
```

Response는 멤버 배열이며, 각 멤버에는 `user`(사용자 이름)가 있습니다. add-users 호출에는 `user`를 사용하세요.

**2단계 – 리소스 그룹에 추가**

1단계에서 가져온 사용자 이름을 일반적인 add-users 요청에 사용하세요:

```http
POST /api/organizations/{org_name}/resource-groups/{resource_group_id}/users
Content-Type: application/json
Body: { "users": [{ "user": "<username from step 1>", "role": "read" }] }
```

**예시: 이메일 1개 (bash)**

```bash
ORG_NAME="my-org"
RG_ID="507f1f77bcf86cd799439011"
EMAIL="member@org.com"

# Step 1: look up member by email (domain must match org's Organization email domain or SSO allowed domains)
MEMBERS=$(curl -s -H "Authorization: Bearer $HF_TOKEN" \
  "https://huggingface.co/api/organizations/$ORG_NAME/members?email=$EMAIL&limit=1")
USERNAME=$(echo "$MEMBERS" | jq -r '(.[0] // {} | .user // "")')
if [ -z "$USERNAME" ]; then
  echo "No member found for $EMAIL"
  exit 1
fi
# Step 2: add to resource group
curl -s -X POST -H "Authorization: Bearer $HF_TOKEN" -H "Content-Type: application/json" \
  -d "{\"users\":[{\"user\":\"$USERNAME\",\"role\":\"read\"}]}" \
  "https://huggingface.co/api/organizations/$ORG_NAME/resource-groups/$RG_ID/users"
```

**예시: 루프에서 여러 이메일 (Python)**

```python
import os
import requests

BASE = "https://huggingface.co"
ORG = "my-org"
RG_ID = "507f1f77bcf86cd799439011"
ROLE = "read"
headers = {"Authorization": f"Bearer {os.environ['HF_TOKEN']}", "Content-Type": "application/json"}

emails = ["member1@org.com", "member2@org.com"]
for email in emails:
    # Step 1: resolve email → username (email domain must match org's Organization email domain or SSO allowed domains)
    r = requests.get(f"{BASE}/api/organizations/{ORG}/members", params={"email": email, "limit": 1}, headers=headers)
    r.raise_for_status()
    members = r.json()
    if not members:
        print(f"No member found for {email}")
        continue
    username = members[0]["user"]
    # Step 2: add that user to the resource group
    add_r = requests.post(
        f"{BASE}/api/organizations/{ORG}/resource-groups/{RG_ID}/users",
        headers=headers,
        json={"users": [{"user": username, "role": ROLE}]},
    )
    if add_r.status_code == 200:
        print(f"Added {username} ({email})")
    else:
        print(f"Failed {email}: {add_r.status_code} {add_r.text}")
```

사용자가 이미 리소스 그룹에 있는 경우 add 호출은 `403`을 반환합니다. 스크립트는 이를 실패로 보고하며, 원하시는 경우 해당 케이스를 건너뛰거나 무시할 수 있습니다.

**제한 사항:** 이메일 필터는 조직에 **조직 이메일 도메인** 및/또는 **SSO 허용 도메인**이 설정되어 있고, 해당 이메일의 도메인이 그 중 하나와 일치할 때만 적용됩니다. 그렇지 않으면 멤버 API를 통해 이메일로 조회할 수 없으며, 이메일 → 사용자 이름 매핑을 위한 다른 소스(예: 자체 디렉터리)가 필요합니다.

### API를 반복하여 일괄 추가

여러 사용자를 **하나의** 리소스 그룹에 한 번 또는 몇 번의 요청으로 추가할 수 있습니다(예: 사용자 이름 목록을 청크로 나누기). 또는 그룹을 반복하며 각 그룹에 대해 add-users 엔드포인트를 호출하여 **여러** 리소스 그룹에 사용자를 추가할 수도 있습니다.

**예시: Bash – 한 요청에 그룹 1개, 사용자 여러 개**

```bash
#!/bin/bash
# Add a list of users to a single resource group.
# Usage: ./add-users-to-rg.sh <org_name> <resource_group_id> <role>

ORG_NAME="${1:-my-org}"
RG_ID="${2:-507f1f77bcf86cd799439011}"
ROLE="${3:-read}"

USERS="member1 member2 member3 member4"
USERS_JSON=$(echo "$USERS" | tr ' ' '\n' | while read u; do
  [ -n "$u" ] && echo "{\"user\":\"$u\",\"role\":\"$ROLE\"}"
done | paste -sd ',' -)

curl -s -w "\nHTTP_STATUS:%{http_code}" -X POST \
  -H "Authorization: Bearer $HF_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"users\":[$USERS_JSON]}" \
  "https://huggingface.co/api/organizations/$ORG_NAME/resource-groups/$RG_ID/users"
```

**예시: Bash – 여러 그룹 반복**

```bash
# Get group IDs and add users to each
curl -s -H "Authorization: Bearer $HF_TOKEN" \
  "https://huggingface.co/api/organizations/my-org/resource-groups" \
  | jq -r '.[].id' \
  | while read -r RG_ID; do
      [ -z "$RG_ID" ] && continue
      echo "Adding users to resource group $RG_ID ..."
      curl -s -X POST -H "Authorization: Bearer $HF_TOKEN" -H "Content-Type: application/json" \
        -d "{\"users\":[$USERS_JSON]}" \
        "https://huggingface.co/api/organizations/my-org/resource-groups/$RG_ID/users"
    done
```

**예시: Python – 하나 또는 여러 그룹에 일괄 추가**

```python
import os
import requests

BASE_URL = "https://huggingface.co"
HF_TOKEN = os.environ.get("HF_TOKEN", "")

def list_resource_groups(org_name: str):
    r = requests.get(
        f"{BASE_URL}/api/organizations/{org_name}/resource-groups",
        headers={"Authorization": f"Bearer {HF_TOKEN}"},
    )
    r.raise_for_status()
    return r.json()

def add_users_to_resource_group(org_name: str, resource_group_id: str, users_with_roles: list):
    """users_with_roles: list of {"user": "username", "role": "read"|"write"|"contributor"|"admin"}"""
    r = requests.post(
        f"{BASE_URL}/api/organizations/{org_name}/resource-groups/{resource_group_id}/users",
        headers={"Authorization": f"Bearer {HF_TOKEN}", "Content-Type": "application/json"},
        json={"users": users_with_roles},
    )
    if r.status_code != 200:
        raise RuntimeError(f"Add users failed {r.status_code}: {r.text}")
    return r.json()

# Example: same users added to every resource group
org_name = "my-org"
role = "read"
usernames = ["member1", "member2", "member3"]
users_with_roles = [{"user": u, "role": role} for u in usernames]

for rg in list_resource_groups(org_name):
    add_users_to_resource_group(org_name, rg["id"], users_with_roles)
```

긴 사용자 이름 목록의 경우, 큰 요청 본문이나 타임아웃을 피하기 위해 청크(예: 요청당 50개)로 나누고 청크마다 API를 한 번씩 호출하세요.

### 중요한 참고 사항

1. **사용자 이름만** — API는 이메일이 아니라 Hugging Face **사용자 이름**을 받습니다. API를 호출하기 전에 이메일 → 사용자 이름 매핑(예: 디렉터리 또는 조직 멤버 목록에서 가져온 것)이 필요합니다.
2. **사용자는 조직에 속해 있어야 합니다** — 요청에 포함된 모든 사용자는 이미 조직의 멤버여야 합니다. 그렇지 않으면 일부 사용자가 조직에 속하지 않았다는 메시지와 함께 `403`가 반환됩니다.
3. **멱등성** — 사용자가 이미 리소스 그룹에 포함된 경우, 백엔드는 해당 요청에 대해 `403`을 반환할 수 있습니다. 스크립트에서 오류를 잡아 계속 진행하거나, 먼저 그룹의 `users` 목록을 가져와 이미 그룹에 있는 사용자를 건너뛰도록 할 수 있습니다.
4. **요청 제한** — 대량 배치의 경우 요청 제한에 도달하지 않도록 요청 사이에 짧은 지연(예: 0.5~1초)을 추가하는 것을 고려해 보세요.
5. **토큰 범위** — 액세스 토큰은 조직에 대해 충분한 권한을 가져야 합니다(일반적으로 최소한 "조직 설정/멤버 관리에 대한 쓰기 액세스" 권한). 토큰을 생성하고 안전하게 저장하세요. 버전 관리 시스템에 커밋하지 마세요.

---

## API를 통해 자동 가입 구성

[Auto-join](./security-resource-groups#auto-join)은 지정된 역할로 조직 구성원을 Resource Group에 자동으로 추가합니다. 이를 API를 통해 활성화하거나 비활성화할 수 있으며, 모든 조직 구성원을 포함할지 Read+ 멤버만 포함할지 선택할 수도 있습니다.

**자동 가입 활성화**

```http
POST /api/organizations/{org_name}/resource-groups/{resource_group_id}/settings
Authorization: Bearer <your_access_token>
Content-Type: application/json

{
  "autoJoin": {
    "enabled": true,
    "role": "read",
    "scope": "read_plus"
  }
}
```

- **경로 매개변수**
  - `org_name`: 조직 슬러그(예: `my-org`).
  - `resource_group_id`: Resource Group의 ID (24자 16진 문자열; [list resource groups endpoint](#list-resource-groups)에서 ID를 가져옵니다).
- **본문**
  - `role`: 자동 추가된 멤버에게 할당할 역할. `"read"`, `"contributor"`, `"write"`, `"admin"`, 또는 `"inherit"` 중 하나입니다.
  - `scope` (선택 사항): 자동으로 추가할 조직 멤버의 범위를 지정합니다. 모든 조직 멤버를 포함하려면 `"all"`을(를) 사용하세요. `no_access` 조직 역할을 가진 멤버를 제외하려면 `"read_plus"`을(를) 사용하세요. 생략하면 기본값은 `"all"`입니다.

Resource Group에 auto-join을 활성화하면 선택된 범위에 해당하는 현재 조직 구성원이 즉시 추가됩니다(backfill).

**자동 가입 비활성화**

`"enabled": false`를 사용하여 동일한 요청을 보내세요. 비활성화할 때 `role` 필드는 필수 사항이 아닙니다:

```http
POST /api/organizations/{org_name}/resource-groups/{resource_group_id}/settings
Authorization: Bearer <your_access_token>
Content-Type: application/json

{
  "autoJoin": {
    "enabled": false
  }
}
```

> [!NOTE]
> auto-join을 비활성화해도 이전에 auto-join된 멤버가 **제거되지 않습니다**. 향후 org 멤버가 자동으로 추가되는 것만 중단됩니다. 기존 멤버는 Resource Group에 그대로 유지됩니다.

## API를 통해 지출 한도 설정

[지출 한도](./security-resource-groups#spend-limits)는 리소스 그룹에 귀속되는 월간 컴퓨트 지출을 제한합니다. 업데이트 엔드포인트를 사용하여 설정합니다:

```http
PATCH /api/organizations/{org_name}/resource-groups/{resource_group_id}
Authorization: Bearer <your_access_token>
Content-Type: application/json

{
  "spendLimits": {
    "total": 500000,
    "spaces": 100000,
    "jobs": 50000
  }
}
```

- **경로 매개변수**
  - `org_name`: 조직 슬러그(예: `my-org`).
  - `resource_group_id`: Resource Group의 ID (24자 16진 문자열; [list resource groups endpoint](#list-resource-groups)에서 ID를 가져옵니다).
- **본문**
  - `spendLimits`: **센트 단위**의 월별 한도. 위의 예시는 총 한도를 5,000달러로 설정하고, Spaces에는 1,000달러, Jobs에는 500달러를 할당합니다.
    - `total`: 모든 제품에서 그룹의 총 지출 한도.
    - `inferenceProviders`, `spaces`, `jobs`, `endpoints`: 총량 한도에 추가로 적용되는 제품별 한도입니다. 두 한도 중 더 엄격한 쪽이 우선 적용됩니다.

보낸 키만 업데이트되고, 나머지는 현재 값을 유지합니다. 한도를 제거하려면 `null`을 보내세요:

```http
PATCH /api/organizations/{org_name}/resource-groups/{resource_group_id}
Authorization: Bearer <your_access_token>
Content-Type: application/json

{
  "spendLimits": {
    "jobs": null
  }
}
```

**예시 (curl)**

```bash
curl -s -X PATCH \
  -H "Authorization: Bearer $HF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"spendLimits": {"total": 500000}}' \
  "https://huggingface.co/api/organizations/my-org/resource-groups/507f1f77bcf86cd799439011"
```

응답에는 `spendLimits`를 포함한 업데이트된 리소스 그룹이 포함됩니다.

## API를 통해 외부 협업자 초대

[외부 초대](./security-resource-groups#external-invitations)를 사용하면 리소스 그룹 관리자가 조직 외부의 사용자를 리소스 그룹에 초대할 수 있습니다. 초대받은 사용자는 `no_access` 조직 역할의 외부 협업자로 참여합니다. 이들은 조직의 유료 좌석 수에 포함됩니다.

**외부 초대 활성화**

Org 관리자는 다음으로 설정을 활성화할 수 있습니다:

```http
POST /api/organizations/{org_name}/resource-groups/settings
Authorization: Bearer <your_access_token>
Content-Type: application/json

{
  "allowExternalInvites": true
}
```

- **본문**
  - `allowExternalInvites` (선택 사항): 리소스 그룹 관리자가 조직 외부의 사용자를 초대할 수 있는지 여부입니다.
  - `minRoleToCreate` (선택 사항): [Resource Groups를 생성](./security-resource-groups#who-can-create-resource-groups)하는 데 필요한 최소 조직 역할입니다.

생략된 필드는 변경되지 않습니다. 현재 설정을 읽으려면 `GET /api/organizations/{org_name}/resource-groups/settings`를 사용하세요.

**사용자 초대**

```http
POST /api/organizations/{org_name}/resource-groups/{resource_group_id}/invite
Authorization: Bearer <your_access_token>
Content-Type: application/json

{
  "username": "partner-user",
  "role": "read"
}
```

- **경로 매개변수**
  - `org_name`: 조직 슬러그(예: `my-org`).
  - `resource_group_id`: Resource Group의 ID (24자 16진 문자열; [list resource groups endpoint](#list-resource-groups)에서 ID를 가져옵니다).
- **본문**
  - `username`: 아직 조직에 가입하지 않은 기존 Hugging Face 사용자의 사용자 이름입니다. 조직 멤버를 추가하려면 대신 [리소스 그룹에 사용자 추가](#add-users-to-a-resource-group)를 사용하세요.
  - `role`: Resource Group에서 초대 대상이 얻는 역할, `"read"` 또는 `"write"`.

사용자가 수락한 후 이메일 초대와 Resource Group에 대한 액세스 권한을 받게 됩니다.

**대기 중인 초대 관리**

- **목록:** `GET /api/organizations/{org_name}/resource-groups/{resource_group_id}/invitations`
- **재전송:** `POST /api/organizations/{org_name}/resource-groups/{resource_group_id}/invitation/{invitation_id}/resend`
- **취소:** `DELETE /api/organizations/{org_name}/resource-groups/{resource_group_id}/invitation/{invitation_id}`

또한 [전체 OpenAPI 사양을 확인](https://huggingface.co/spaces/huggingface/openapi#tag/resource-groups)할 수 있습니다

**일반적인 오류:**

- `403` — 조직에서 외부 초대 기능이 비활성화되어 있습니다.
- `409` — 사용자가 이미 해당 조직의 멤버이거나, 이미 대기 중인 초대장을 보유하고 있습니다.

## API를 통해 멤버 계정 유형 변경

조직 구성원을 [외부 협업자](./security-sso-user-management#external-collaborators)(SSO 불필요)로 전환하거나, 다시 구성원으로 복원합니다. 유료 플랜과 조직에 대한 **Write**(또는 Admin) 권한이 필요합니다. SCIM을 통해 구성원이 프로비저닝되는 관리 사용자 조직에서는 사용할 수 없습니다.

> [!WARNING]
> 사용자의 계정 유형을 변경해도 역할은 변경되지 않습니다. 사용자의 역할을 변경하려면 [API를 통해 멤버 역할 변경](https://huggingface.co/docs/hub/main/en/programmatic-user-access-control#change-member-role-via-api)을 참조하세요.

```http
PUT /api/organizations/{org_name}/members/{username}/account-type
Authorization: Bearer <your_access_token>
Content-Type: application/json

{
  "accountType": "external"
}
```

- **본문**
  - `accountType`: 멤버를 외부 협업자로 전환하려면 `"external"`, 다시 멤버로 전환하려면 `"member"`를 사용합니다.

