조직에 구성원 초대
POST /v1/invitations · 권한 invitations:write
이메일 주소를 대상으로 조직 가입 초대를 만듭니다. organization_id 없이 생성하면 환경 초대가 됩니다. 이는 초대 전용 가입 모드의 가입 링크이며, 멤버십을 만들지 않고 역할도 지정할 수 없습니다(role_ids 요청 시 422 validation_failed 반환). 응답에는 organization_id: null가 없습니다. delivery은 필수입니다. email을 사용하면 환경의 초대 템플릿(delivery_status: queued)으로 초대 이메일을 발송하며, 링크는 이메일에만 포함되고 응답에는 accept_url이 없습니다. link_only을 사용하면 이메일을 보내지 않고 링크를 반환하므로 직접 공유하십시오. 수락 링크(accept_url)는 이 응답에서만 한 번 반환되며, 이후 어떤 엔드포인트도 반환하지 않습니다. 응답에는 Cache-Control: no-store이 포함되며, 같은 Idempotency-Key에 대해 재전송된 응답에는 링크가 빠지고 secret_redacted: true이 포함됩니다. 배포에 초대 이메일이 설정되지 않은 경우(프로덕션이 아닌 환경에서만), email 전달은 501 not_implemented을 반환하며 아무것도 기록되지 않습니다. 같은 조직과 이메일에 같은 역할의 대기 중 초대가 이미 있으면 새 링크로 재발송되며, 응답은 200입니다. 만료되었으나 아직 처리되지 않은 대기 초대는 같은 요청에서 expired로 표시되고 새 초대가 기록됩니다(invitation.expired 작업으로 감사 기록). 같은 역할의 대기 email 초대는 이메일로 재발송되며, 응답은 200이고 delivery: email을 포함하며 accept_url은 없습니다. 이 쓰기 작업은 invitation.created 작업으로 감사 기록됩니다.
요청
| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
organization_id |
문자열 | 아니요 | 조직 ID(org_…). 환경 초대(역할 없음)를 만들려면 생략하십시오. |
email |
문자열 | 예 | 초대받는 사람의 이메일 주소, 최대 320자. |
delivery |
문자열 | 예 | email(링크는 이메일에만 포함) 또는 link_only(링크는 이 응답에만 포함). |
role_ids |
문자열[] | 아니요 | 수락 시 부여할 역할(rol_…), 최대 10개. 비어 있으면 기본 구성원 역할. |
application_id |
문자열 | 아니요 | 초대받은 사람이 들어갈 애플리케이션(app_…). 이 환경에 존재해야 합니다. |
ttl_days |
정수 | 아니요 | 1–30. 기본값은 환경의 invitation_ttl_days(7)입니다. |
응답
초대와 수락 링크가 포함된 201 Created을 반환합니다(대기 초대를 재발송한 경우 200 OK).
{
"id": "inv_01j9xt9v3w4y8z0a2b4c6d8e0g",
"organization_id": "org_01j9xk3m7q8r2s4t6v8w0y2z4a",
"email": "ada@example.com",
"role_ids": [
"rol_01j9xr7s1t2w6x8y0z2a4b6c8e"
],
"application_id": null,
"delivery": "link_only",
"delivery_status": "not_sent",
"status": "pending",
"send_count": 1,
"last_sent_at": "2026-10-12T09:31:00.123456Z",
"expires_at": "2026-10-19T09:31:00.123456Z",
"accepted_user_id": null,
"accepted_at": null,
"revoked_at": null,
"created_at": "2026-10-12T09:31:00.123456Z",
"updated_at": "2026-10-12T09:31:00.123456Z",
"version": 1,
"accept_url": "https://acme.eu.keenauth.app/u/login?invitation=<token>"
}
오류
| HTTP | 코드 | 발생 조건 |
|---|---|---|
| 404 | not_found |
이 환경에 조직 또는 애플리케이션이 없습니다. |
| 409 | invitation_already_pending |
이 이메일에 대해 다른 역할을 가진 대기 초대가 있습니다. |
| 409 | membership_already_exists |
이 이메일은 이미 구성원에게 속해 있습니다. |
| 409 | organization_disabled |
조직이 비활성화되어 있습니다. |
| 422 | invitation_invalid |
이 값으로는 초대를 만들 수 없습니다. |
| 422 | validation_failed |
필드가 없거나 잘못되었습니다. |
| 429 | invite_rate_limited |
초대가 10분 이내에 재발송되었거나 이미 5회 재발송되었습니다. |
| 501 | not_implemented |
delivery이 email이고 배포에 초대 이메일이 설정되지 않았습니다. |
| 401 | unauthenticated |
자격 증명이 없거나 잘못되었거나 취소되었습니다. |
| 403 | insufficient_permissions |
자격 증명에 필요한 권한이 없습니다. 권한이 높은(is_privileged) 역할을 할당하려면 roles:write도 필요합니다. 없으면 아무것도 기록되지 않으며 required_permissions에 두 권한이 모두 나열됩니다. |
| 429 | rate_limited |
요청 한도를 초과했습니다. Retry-After 기간 후에 다시 시도하십시오. |
| 503 | service_unavailable |
종속 서비스를 일시적으로 사용할 수 없습니다. Retry-After 기간 후에 다시 시도하십시오. |
예시
curl -i -X POST "https://api.eu.keenauth.com/v1/invitations" \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"organization_id":"org_01j9xk3m7q8r2s4t6v8w0y2z4a","email":"ada@example.com","delivery":"link_only","role_ids":["rol_01j9xr7s1t2w6x8y0z2a4b6c8e"]}'
개인정보
이 엔드포인트는 개인정보를 포함합니다: 조직 멤버십과 초대. KeenAuth API의 개인정보에서 저장되는 항목, 보관 기간, 삭제 방법을 설명합니다. 어떤 필드에도 특수 범주의 개인정보(건강, 생체 정보, 종교, 정치적 견해, 성적 지향)를 보내지 마십시오.