apps
create/update apps, access, comments, env vars, static release, staging, raw-db toggle, browse-policy
A collection of operations for the app itself. Creation, updates, access control, comments, environment variables, the raw DB toggle — the whole app lifecycle is here. The browse-policy that restricts app-data browsing to the owner group and the browse-log (resource-access-logs) reads are also on this page. The tables are sorted in path alphabetical order. The operational view of who can see what is covered in the access management guide.
31 operations — create/update apps, access, comments, env vars, static release, staging, raw-db toggle, browse-policy, browse logs
GET /api/v1/apps/discover
appsGetApiV1AppsDiscover
모든 tenant 의 공개 승인·배포 앱을 한 데 모아 반환한다.
- 호출 권한: 인증된 사용자. 결과는 caller 의 멤버십/소유권과 무관 — visibility=public|internet AND review_status=approved AND status=deployed 인 앱만 노출.
- sort 는
newest(default) /oldest/likes/subscribers/name. JSON:API 표기-created_at/created_at(oldest) /-like_count/-subscriber_count/name도 동일하게 매핑. 잘못된 값이면 newest fallback. created_within_days가 양수면 최근 N일 내 생성된 앱만 (생성일 컷오프).- 페이지네이션은
page(1-based, 기본 1) + 페이지 크기per_page(또는 aliaslimit, 기본 50, 최대 200).total은 필터 적용된 전체 개수 (page 수 계산용). - 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps.discover(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1AppsDiscover(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1AppsDiscover(pathParams, query, body) — async: appsGetApiV1AppsDiscoverAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1AppsDiscover(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_apps_discover(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_apps_discover(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1AppsDiscover", pathParams, query, body) |
Query parameters — pass via query (string values)
| Name | Type | Description |
|---|---|---|
q | string | 검색 키워드 (이름 / slug / 설명 / 카테고리명 부분 매칭) |
category | string | 카테고리 slug 필터 |
sort | string | 정렬 키 |
created_within_days | integer | 최근 N일 내 생성된 앱만 (양수일 때만 적용) |
page | integer | 페이지 번호 (1-based, 기본 1) |
per_page | integer | 페이지 크기 (기본 50, 최대 200; alias limit) |
Response — 200 · 공개 앱 목록
| Name | Type | Description |
|---|---|---|
items | array<object> | |
nextCursor (wire: next_cursor) | string | |
total | integer |
Error statuses: 401 500 — Error handling
GET /api/v1/apps/search
appsGetApiV1AppsSearch
카탈로그에서 앱을 키워드/카테고리/상태/정렬로 검색한다.
- 호출 권한: 인증된 사용자. 결과는 caller 의 멤버십·access·visibility 로 자동 필터.
- sort 는
newest(default) /likes/subscribers/name. JSON:API 표기-created_at/-like_count/-subscriber_count/name도 동일하게 매핑. 잘못된 값이면 newest fallback. - visibility 필터는
private/invite_only/public/internet. 잘못된 값이면 무시. - status 필터는
draft/deployed/archived. 다음 4 표기 다 인식 (multi-value OR 매칭): 평탄 단일status=archived, JSON:API 단일filter[status]=archived, CSV multistatus_in=archived,draft(FE generated-types 권장), JSON:API 배열filter[status][]=archived&filter[status][]=draft. 잘못된 값은 폐기 후 매칭. - 페이지 크기는
limit또는 aliasper_page(둘 다 있으면 limit 우선). 기본 50, 최대 200. - 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps.discover.search(…) — 리소스 모델 — 인자·반환 타입은 패키지의 TypeScript 정의 참조 |
| go | client.Apps.AppsGetApiV1AppsSearch(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1AppsSearch(pathParams, query, body) — async: appsGetApiV1AppsSearchAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1AppsSearch(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_apps_search(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_apps_search(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1AppsSearch", pathParams, query, body) |
Query parameters — pass via query (string values)
| Name | Type | Description |
|---|---|---|
q | string | 검색 키워드 (이름 / slug / 설명에서 부분 매칭) |
category | string | 카테고리 slug 필터 |
sort | string | 정렬 키 |
visibility | string | 가시성 필터 |
status | string | 상태 필터 (평탄 단일) |
status_in | string | 상태 필터 (CSV multi, OR 매칭. 예: archived,draft) |
filter[status] | string | 상태 필터 (JSON:API 단일) |
limit | integer | 페이지 크기 (기본 50, 최대 200) |
per_page | integer | 페이지 크기 alias (limit 우선) |
cursor | string | 다음 페이지 커서 |
Response — 200 · 검색 결과
| Name | Type | Description |
|---|---|---|
items | array<object> | |
nextCursor (wire: next_cursor) | string | |
total | integer |
Error statuses: 401 500 — Error handling
DELETE /api/v1/apps/{appID}
appsDeleteApiV1AppsByAppID
앱을 soft-delete 한다 — 카탈로그에서 숨김 처리하지만 데이터/스키마는 보존.
- 호출 권한: 앱 소유자 / 같은 테넌트의 admin / platform admin (gate denial → 403).
- 이미 삭제된 앱이면 409 (ErrAlreadyDeleted).
- 부수 효과: 도메인 이벤트 (
AppDeleted) 가 발행됨. 영구 삭제는 별 endpoint.
| Language | Call |
|---|---|
| node | sdk.apps(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsDeleteApiV1AppsByAppID(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsDeleteApiV1AppsByAppID(pathParams, query, body) — async: appsDeleteApiV1AppsByAppIDAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsDeleteApiV1AppsByAppID(pathParams, query, body) — suspend |
| python | client.apps.apps_delete_api_v1_apps_by_app_id(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_delete_api_v1_apps_by_app_id(path_params: …, query: …, body: …) |
| generic | request("appsDeleteApiV1AppsByAppID", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 204 · 삭제 성공 (no content)
No body → the SDK returns an empty map {}
Error statuses: 400 401 403 404 409 500 — Error handling
GET /api/v1/apps/{appID}
appsGetApiV1AppsByAppID
앱 UUID 로 단건 조회. 멀티 테넌트를 가로지른다.
- 호출 권한: 인증된 사용자. visibility 가
private이면 owner / tenant admin / platform admin 만 볼 수 있음 (이외 → 404 로 위장). - path 의 appID 가 UUID 형식이 아니면 400.
- 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1AppsByAppID(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1AppsByAppID(pathParams, query, body) — async: appsGetApiV1AppsByAppIDAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1AppsByAppID(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_apps_by_app_id(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_apps_by_app_id(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1AppsByAppID", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 200 · 앱
| Name | Type | Description |
|---|---|---|
accessUrl (wire: access_url) | string | AccessURL 은 앱의 접속 URL (https://{subdomain}.{tenant_slug}.{base_domain}). subdomain 미설정 앱은 null — FE 는 앱 상세로 fallback. list (Search / List / Discover / users/me/apps embed) 와 단건 (Get) 응답에서 batch enrich 로 채워짐. Create 응답은 항상 null (subdomain 유무와 무관하게 생성 직후엔 enrich 안 함). |
authMode (wire: auth_mode) | string | AuthMode 는 앱 dataapi 가 받는 대표 인증 방식. 가능값: cookie / bearer / api_key / anonymous. 기본 bearer. |
callsCount (wire: calls_count) | integer | CallsCount 는 누적 dataapi 호출 수. denormalized counter — v1 에선 갱신 로직 없이 항상 0; 미래 phase 에서 gateway_log projection 이 채움. |
category | any | Category 는 앱 카테고리의 inline 표현. 단건 조회와 list 응답 (Search / List / Discover) 모두에서 batch enrich 로 채워짐. 카테고리가 없거나 missing 이면 필드 자체가 omit. AppsCount 는 enrich 시 0 (이 컨텍스트에서 카테고리 자체의 분포는 의미 없음). |
categoryId (wire: category_id) | string | CategoryID 는 카테고리 UUID. 카테고리가 없으면 omit. |
costCenter (wire: cost_center) | string | CostCenter 는 비용 귀속 라벨 (팀/부서). null = 미할당 (spec 003). |
createdAt (wire: created_at) | string | CreatedAt 은 생성 시각 (UTC). |
dataScopes (wire: data_scopes) | array<string> | DataScopes 는 앱이 노출하는 dataapi scope 라벨 목록. 자유 형식. 빈 배열이면 scope 정의 없음 — handler 가 scope 검사 안 함. |
deletedAt (wire: deleted_at) | string | DeletedAt 은 soft-delete 시각 (UTC). 살아있는 앱이면 omit. |
deployMethod (wire: deploy_method) | string | DeployMethod is the immutable deployment strategy: docker / compose / static. |
description | string | Description 은 앱 설명 (선택, 최대 20000자). |
iconDarkUrl (wire: icon_dark_url) | string | IconDarkURL 은 다크 모드용 아이콘 URL (선택). 없으면 FE 가 IconURL 로 fallback. |
iconUrl (wire: icon_url) | string | IconURL 은 아이콘 이미지 URL (선택, 라이트 모드용). |
id | string | ID 는 앱 UUID. |
lastDeploymentStatus (wire: last_deployment_status) | string | LastDeploymentStatus 는 가장 최근 deployment 의 raw 도메인 상태. 가능값: pending / running (배포 진행 중) / succeeded (라이브) / failed / cancelled. deployment 가 한 번도 없는 앱 (예: 방금 생성된 draft) 은 null. POST /apps (Create) 응답은 항상 null — 생성 직후엔 deployment 가 없음. List/Get/Search/PATCH 응답은 모두 enrich 된 값. 주의: backend enum 의 running 은 "배포 작업 진행 중" 이고 succeeded 가 "앱이 라이브 (운영중)" 다. FE 매핑 시 둘 혼동 X. |
likeCount (wire: like_count) | integer | LikeCount 는 좋아요 누적 수. |
name | string | Name 은 사람이 읽는 표시 이름. |
operatingStatus (wire: operating_status) | string | OperatingStatus 는 운영 상태 rollup. archived (보관됨) / live (운영중) / dev (개발중). status·review_status·visibility 에서 파생된 요약일 뿐 — 위 raw 필드들은 그대로 응답에 남아 이 rollup 이 다른 상태를 가리지 않는다. archived → status archived (최우선) live → review_status approved + visibility invite_only/public/internet dev → 그 외 (심사 전/대기/반려, 또는 승인됐지만 private) |
owner | any | Owner 는 앱 owner 의 inline 요약 (이름·아바타). 단건 조회 (GET /api/v1/apps/{appID}) 와 list 응답 (Search / List / Discover) 모두에서 batch enrich 로 채워짐 — FE 가 row 마다 단건 GET 을 부르는 N+1 을 피하기 위함. owner_id 가 가리키는 사용자가 missing/soft-deleted 면 필드 자체가 omit. |
ownerId (wire: owner_id) | string | OwnerID 는 앱 소유자 (생성자) 의 사용자 UUID. |
productionDeploymentId (wire: production_deployment_id) | string | ProductionDeploymentID 는 지금 prod 가 서빙 중인 deployment UUID. 성공 배포가 한 번도 없으면 null. 버전 번호는 releases API 에서 조회. |
resourcePreset (wire: resource_preset) | string | ResourcePreset 는 Resources 값을 카탈로그와 매칭한 파생 라벨 (XS/S/M/L/XL 또는 커스텀). 저장하지 않고 매번 계산. (spec 014) |
resources | any | Resources 는 Pod CPU/메모리 사양 (저장된 값 4개). (spec 014) |
resumedAt (wire: resumed_at) | string | ResumedAt 은 마지막 resume 시각 (UTC, spec 312). 한 번도 suspend 한 적 없으면 omit. 현재 suspended_at != nil 이어도 옛 resume 이력이 있으면 값이 남아있을 수 있음 (이력 용도). |
reviewStatus (wire: review_status) | string | ReviewStatus 는 심사 상태. not_submitted / pending / approved / rejected. |
schemaName (wire: schema_name) | string | SchemaName 은 앱 전용 Postgres schema 이름. 생성 시 자동 발급. |
sharedTablesCount (wire: shared_tables_count) | integer | SharedTablesCount 는 이 앱이 다른 앱에 grant 한 dynamic_table 수. denormalized counter — v1 에선 항상 0; 미래 phase 에서 table_grant projection 이 채움. |
slug | string | Slug 는 URL 식별자. [a-z0-9-]+. 같은 테넌트 안 unique. |
stagingDeploymentId (wire: staging_deployment_id) | string | StagingDeploymentID 는 지금 staging 이 서빙 중인 deployment UUID. 옵트인 안 했거나 staging 배포 전이면 null. |
stagingEnabled (wire: staging_enabled) | boolean | StagingEnabled 는 스테이징 옵트인 여부 (spec 016). true 면 push 가 staging 에만 반영되고 prod 는 promote(심사 승인)로만 바뀜. staging URL 은 access_url 의 subdomain 에 --staging 을 붙인 호스트. |
status | string | Status 는 앱 배포 상태 (spec 324). draft (배포 전) / deployed (배포됨) / archived (보관됨). 배포 성공 시 draft→deployed 자동 전이. soft-delete 여부는 별 deleted_at, 최근 배포 attempt 의 raw 상태는 별 last_deployment_status. |
subdomain | string | Subdomain 은 접속 주소 (선택, 2~32자 소문자/숫자/하이픈). 미설정 상태면 omit — 다음 deploy 시 412 까지 deploy 못 함. |
subscriberCount (wire: subscriber_count) | integer | SubscriberCount 는 앱을 "받은" (UserAppAccess grant) 사용자 수. |
summary | string | Summary 는 앱의 "한 줄 소개" (선택, 최대 60자). description(상세 설명) 과 분리된 짧은 소개. 미설정이면 omit. |
suspendedAt (wire: suspended_at) | string | SuspendedAt 은 runtime suspend 시각 (UTC, spec 312). non-nil 이면 K8s namespace 가 정리된 상태 (pod 0). status 와 직교 — 어느 lifecycle 단계든 suspend 가능. live 상태면 omit. |
tenantId (wire: tenant_id) | string | TenantID 는 앱이 속한 테넌트 UUID. |
updatedAt (wire: updated_at) | string | UpdatedAt 은 마지막 수정 시각 (UTC). |
visibility | string | Visibility 는 카탈로그 노출 범위. private / invite_only / public / internet(익명 포함 인터넷 전체). |
Error statuses: 400 401 404 500 — Error handling
PATCH /api/v1/apps/{appID}
appsPatchApiV1AppsByAppID
앱의 이름·설명·아이콘·카테고리·가시성·subdomain·resource_preset 을 부분 갱신한다 (PATCH 시맨틱 — 보낸 항목만).
- 호출 권한: 앱 소유자 / 같은 테넌트의 admin / platform admin (gate
RequireAppOwnerOrAdmin— 아니면 403). - deploy_method 는 immutable — body 에 포함 시 400 ErrImmutableField.
- visibility 는
private/invite_only/public/internet. 이 API 로는 현재 값보다 좁게만 바꿀 수 있다 (private포함) — 넓히려면 공개 신청(심사) 필요. 위반 시 409visibility_widen_not_allowed. - resource_preset 은 XS/S/M/L/XL. 정의되지 않은 값이면 400. live 앱이면 즉시 파드에 반영(best-effort).
- subdomain 클리어는
clear_subdomain: true. 빈 문자열은 ErrSubdomainInvalid (400) — 명시적 clear flag 사용. - cost_center 는 비용 귀속 라벨 (팀/부서). 비우려면
clear_cost_center: true. 빈 문자열은 미할당(null)으로 정규화 (spec 003). - summary 는 "한 줄 소개" (최대 60자, rune 기준). 빈 문자열이면 한 줄 소개 제거. description(상세 설명) 과 별개 필드.
- 부수 효과: 도메인 이벤트 (
AppUpdated) 가 발행됨.
| Language | Call |
|---|---|
| node | sdk.apps(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsPatchApiV1AppsByAppID(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsPatchApiV1AppsByAppID(pathParams, query, body) — async: appsPatchApiV1AppsByAppIDAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsPatchApiV1AppsByAppID(pathParams, query, body) — suspend |
| python | client.apps.apps_patch_api_v1_apps_by_app_id(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_patch_api_v1_apps_by_app_id(path_params: …, query: …, body: …) |
| generic | request("appsPatchApiV1AppsByAppID", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Request body — pass via body, wire keys (snake_case) as-is
| Name | Type | Description |
|---|---|---|
auth_mode | string | AuthMode 는 새 대표 인증 방식 (선택). cookie / bearer / api_key / anonymous. 잘못된 값이면 400 ErrInvalidAuthMode. |
category_id | string | CategoryID 는 새 카테고리 UUID (선택). 카테고리를 비우려면 ClearCategory 를 true 로. |
clear_category | boolean | ClearCategory 가 true 면 카테고리를 NULL 로. CategoryID 와 동시에 보내면 ClearCategory 가 우선. |
clear_cost_center | boolean | ClearCostCenter 가 true 면 비용 귀속 라벨을 비움 (미할당). CostCenter 와 동시에 보내면 ClearCostCenter 가 우선. |
clear_subdomain | boolean | ClearSubdomain 이 true 면 접속 주소를 비움 — 다음 deploy 시 412 까지 deploy 못 함. |
cost_center | string | CostCenter 는 비용 귀속 라벨 (팀/부서, 선택). nil = 변경 없음. 비우려면 ClearCostCenter 를 true 로. cost BC 가 워크로드 라벨로 전파해 비용을 팀 단위로 집계 (spec 003). |
data_scopes | array<string> | DataScopes 는 새 scope 라벨 목록 (선택). nil = 변경 없음, 빈 배열 = 전부 삭제. 도메인이 빈/중복 entry 정리. |
deploy_method | string | DeployMethod 는 immutable — 값을 보내면 400 ErrImmutableField. 무시 안 됨. |
description | string | Description 은 새 설명 (선택). 최대 20000자. 빈 문자열이면 설명 제거. |
icon_dark_url | string | IconDarkURL 은 새 다크 모드 아이콘 URL (선택). |
icon_url | string | IconURL 은 새 아이콘 URL (선택, 라이트 모드용). |
name | string | Name 은 새 표시 이름 (선택). 1~80자. |
resource_preset | string | ResourcePreset 는 새 Pod 사양 프리셋 (선택). XS / S / M / L / XL. 정의되지 않은 값이면 400. live 앱이면 즉시 파드에 반영(best-effort). (spec 014) |
subdomain | string | Subdomain 은 새 접속 주소 (선택). 비우려면 ClearSubdomain 을 true 로. |
summary | string | Summary 는 새 "한 줄 소개" (선택). 최대 60자(rune). 빈 문자열이면 한 줄 소개 제거. |
visibility | string | Visibility 는 새 가시성 (선택). private / invite_only / public / internet. 현재 값보다 좁게만 지정 가능 — 넓히려면 공개 신청(심사) 필요, 위반 시 409 visibility_widen_not_allowed. |
Response — 200 · 수정된 앱
| Name | Type | Description |
|---|---|---|
accessUrl (wire: access_url) | string | AccessURL 은 앱의 접속 URL (https://{subdomain}.{tenant_slug}.{base_domain}). subdomain 미설정 앱은 null — FE 는 앱 상세로 fallback. list (Search / List / Discover / users/me/apps embed) 와 단건 (Get) 응답에서 batch enrich 로 채워짐. Create 응답은 항상 null (subdomain 유무와 무관하게 생성 직후엔 enrich 안 함). |
authMode (wire: auth_mode) | string | AuthMode 는 앱 dataapi 가 받는 대표 인증 방식. 가능값: cookie / bearer / api_key / anonymous. 기본 bearer. |
callsCount (wire: calls_count) | integer | CallsCount 는 누적 dataapi 호출 수. denormalized counter — v1 에선 갱신 로직 없이 항상 0; 미래 phase 에서 gateway_log projection 이 채움. |
category | any | Category 는 앱 카테고리의 inline 표현. 단건 조회와 list 응답 (Search / List / Discover) 모두에서 batch enrich 로 채워짐. 카테고리가 없거나 missing 이면 필드 자체가 omit. AppsCount 는 enrich 시 0 (이 컨텍스트에서 카테고리 자체의 분포는 의미 없음). |
categoryId (wire: category_id) | string | CategoryID 는 카테고리 UUID. 카테고리가 없으면 omit. |
costCenter (wire: cost_center) | string | CostCenter 는 비용 귀속 라벨 (팀/부서). null = 미할당 (spec 003). |
createdAt (wire: created_at) | string | CreatedAt 은 생성 시각 (UTC). |
dataScopes (wire: data_scopes) | array<string> | DataScopes 는 앱이 노출하는 dataapi scope 라벨 목록. 자유 형식. 빈 배열이면 scope 정의 없음 — handler 가 scope 검사 안 함. |
deletedAt (wire: deleted_at) | string | DeletedAt 은 soft-delete 시각 (UTC). 살아있는 앱이면 omit. |
deployMethod (wire: deploy_method) | string | DeployMethod is the immutable deployment strategy: docker / compose / static. |
description | string | Description 은 앱 설명 (선택, 최대 20000자). |
iconDarkUrl (wire: icon_dark_url) | string | IconDarkURL 은 다크 모드용 아이콘 URL (선택). 없으면 FE 가 IconURL 로 fallback. |
iconUrl (wire: icon_url) | string | IconURL 은 아이콘 이미지 URL (선택, 라이트 모드용). |
id | string | ID 는 앱 UUID. |
lastDeploymentStatus (wire: last_deployment_status) | string | LastDeploymentStatus 는 가장 최근 deployment 의 raw 도메인 상태. 가능값: pending / running (배포 진행 중) / succeeded (라이브) / failed / cancelled. deployment 가 한 번도 없는 앱 (예: 방금 생성된 draft) 은 null. POST /apps (Create) 응답은 항상 null — 생성 직후엔 deployment 가 없음. List/Get/Search/PATCH 응답은 모두 enrich 된 값. 주의: backend enum 의 running 은 "배포 작업 진행 중" 이고 succeeded 가 "앱이 라이브 (운영중)" 다. FE 매핑 시 둘 혼동 X. |
likeCount (wire: like_count) | integer | LikeCount 는 좋아요 누적 수. |
name | string | Name 은 사람이 읽는 표시 이름. |
operatingStatus (wire: operating_status) | string | OperatingStatus 는 운영 상태 rollup. archived (보관됨) / live (운영중) / dev (개발중). status·review_status·visibility 에서 파생된 요약일 뿐 — 위 raw 필드들은 그대로 응답에 남아 이 rollup 이 다른 상태를 가리지 않는다. archived → status archived (최우선) live → review_status approved + visibility invite_only/public/internet dev → 그 외 (심사 전/대기/반려, 또는 승인됐지만 private) |
owner | any | Owner 는 앱 owner 의 inline 요약 (이름·아바타). 단건 조회 (GET /api/v1/apps/{appID}) 와 list 응답 (Search / List / Discover) 모두에서 batch enrich 로 채워짐 — FE 가 row 마다 단건 GET 을 부르는 N+1 을 피하기 위함. owner_id 가 가리키는 사용자가 missing/soft-deleted 면 필드 자체가 omit. |
ownerId (wire: owner_id) | string | OwnerID 는 앱 소유자 (생성자) 의 사용자 UUID. |
productionDeploymentId (wire: production_deployment_id) | string | ProductionDeploymentID 는 지금 prod 가 서빙 중인 deployment UUID. 성공 배포가 한 번도 없으면 null. 버전 번호는 releases API 에서 조회. |
resourcePreset (wire: resource_preset) | string | ResourcePreset 는 Resources 값을 카탈로그와 매칭한 파생 라벨 (XS/S/M/L/XL 또는 커스텀). 저장하지 않고 매번 계산. (spec 014) |
resources | any | Resources 는 Pod CPU/메모리 사양 (저장된 값 4개). (spec 014) |
resumedAt (wire: resumed_at) | string | ResumedAt 은 마지막 resume 시각 (UTC, spec 312). 한 번도 suspend 한 적 없으면 omit. 현재 suspended_at != nil 이어도 옛 resume 이력이 있으면 값이 남아있을 수 있음 (이력 용도). |
reviewStatus (wire: review_status) | string | ReviewStatus 는 심사 상태. not_submitted / pending / approved / rejected. |
schemaName (wire: schema_name) | string | SchemaName 은 앱 전용 Postgres schema 이름. 생성 시 자동 발급. |
sharedTablesCount (wire: shared_tables_count) | integer | SharedTablesCount 는 이 앱이 다른 앱에 grant 한 dynamic_table 수. denormalized counter — v1 에선 항상 0; 미래 phase 에서 table_grant projection 이 채움. |
slug | string | Slug 는 URL 식별자. [a-z0-9-]+. 같은 테넌트 안 unique. |
stagingDeploymentId (wire: staging_deployment_id) | string | StagingDeploymentID 는 지금 staging 이 서빙 중인 deployment UUID. 옵트인 안 했거나 staging 배포 전이면 null. |
stagingEnabled (wire: staging_enabled) | boolean | StagingEnabled 는 스테이징 옵트인 여부 (spec 016). true 면 push 가 staging 에만 반영되고 prod 는 promote(심사 승인)로만 바뀜. staging URL 은 access_url 의 subdomain 에 --staging 을 붙인 호스트. |
status | string | Status 는 앱 배포 상태 (spec 324). draft (배포 전) / deployed (배포됨) / archived (보관됨). 배포 성공 시 draft→deployed 자동 전이. soft-delete 여부는 별 deleted_at, 최근 배포 attempt 의 raw 상태는 별 last_deployment_status. |
subdomain | string | Subdomain 은 접속 주소 (선택, 2~32자 소문자/숫자/하이픈). 미설정 상태면 omit — 다음 deploy 시 412 까지 deploy 못 함. |
subscriberCount (wire: subscriber_count) | integer | SubscriberCount 는 앱을 "받은" (UserAppAccess grant) 사용자 수. |
summary | string | Summary 는 앱의 "한 줄 소개" (선택, 최대 60자). description(상세 설명) 과 분리된 짧은 소개. 미설정이면 omit. |
suspendedAt (wire: suspended_at) | string | SuspendedAt 은 runtime suspend 시각 (UTC, spec 312). non-nil 이면 K8s namespace 가 정리된 상태 (pod 0). status 와 직교 — 어느 lifecycle 단계든 suspend 가능. live 상태면 omit. |
tenantId (wire: tenant_id) | string | TenantID 는 앱이 속한 테넌트 UUID. |
updatedAt (wire: updated_at) | string | UpdatedAt 은 마지막 수정 시각 (UTC). |
visibility | string | Visibility 는 카탈로그 노출 범위. private / invite_only / public / internet(익명 포함 인터넷 전체). |
Error statuses: 400 401 402 403 404 409 412 500 — Error handling
DELETE /api/v1/apps/{appID}/access
appsDeleteApiV1AppsByAppIDAccess
현재 사용자가 자기 앱 access 를 회수한다.
- 호출 권한: 인증된 사용자 (본인 access 만 회수).
- 받지 않은 앱이면 404 (ErrAccessNotFound).
- app_id 가 UUID 형식이 아니면 400.
- 부수 효과:
UserAppAccess행 삭제 및 앱의subscriber_count감소.
| Language | Call |
|---|---|
| node | sdk.apps.access(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsDeleteApiV1AppsByAppIDAccess(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsDeleteApiV1AppsByAppIDAccess(pathParams, query, body) — async: appsDeleteApiV1AppsByAppIDAccessAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsDeleteApiV1AppsByAppIDAccess(pathParams, query, body) — suspend |
| python | client.apps.apps_delete_api_v1_apps_by_app_id_access(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_delete_api_v1_apps_by_app_id_access(path_params: …, query: …, body: …) |
| generic | request("appsDeleteApiV1AppsByAppIDAccess", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 204 · 해제 성공 (no content)
No body → the SDK returns an empty map {}
Error statuses: 400 401 404 500 — Error handling
POST /api/v1/apps/{appID}/access
appsPostApiV1AppsByAppIDAccess
현재 사용자가 자신에게 앱 접근 권한을 부여한다 (self-grant — 사용자가 직접 앱을 "받는" 흐름).
- 호출 권한: 인증된 사용자 + 앱이 속한 tenant 의 active 멤버.
- 앱 visibility 가
public또는internet일 때만 가능. invite_only / private 은 403 (ErrSelfGrantNotAllowed) — invite_only 는 owner/admin 의 invite 가 필요하고, private 은UserAppAccess행이 access_rule 에 반영되지 않아 의미 없음. - 이미 받은 앱이면 409 (ErrAlreadyAccessed → ErrInviteAlreadyExists).
- 다른 tenant 사용자가 호출하면 400 (ErrInviteCrossTenant).
- app_id 가 UUID 형식이 아니면 400.
- 부수 효과:
UserAppAccess행 생성 및 앱의subscriber_count증가.
| Language | Call |
|---|---|
| node | sdk.apps.access(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsPostApiV1AppsByAppIDAccess(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsPostApiV1AppsByAppIDAccess(pathParams, query, body) — async: appsPostApiV1AppsByAppIDAccessAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsPostApiV1AppsByAppIDAccess(pathParams, query, body) — suspend |
| python | client.apps.apps_post_api_v1_apps_by_app_id_access(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_post_api_v1_apps_by_app_id_access(path_params: …, query: …, body: …) |
| generic | request("appsPostApiV1AppsByAppIDAccess", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 201 · 받은 앱 access
| Name | Type | Description |
|---|---|---|
allowedScopes (wire: allowed_scopes) | array<string> | AllowedScopes 는 허용된 scope 문자열 (예: data.read, data.write). |
app | any | App 은 access 대상 앱의 inline 요약 (name / icon / access_url 등). GET /users/me/apps (ListMine) 응답에서만 batch enrich 로 채워짐 — FE 가 "내 업무공간" 카드를 row 마다 단건 GET 없이 그릴 수 있게. Me / Grant / Invite 응답에선 omit. fetch 실패 / permanently_deleted 면 omit. |
appId (wire: app_id) | string | AppID 는 대상 앱 UUID. |
appRole (wire: app_role) | string | AppRole — caller 의 L2 gate 효과적 역할 (CLI gap G-P3-006). 값은 appdomain.DeriveAppRole 의 6-enum (owner | platform_admin | tenant_admin | app_member | tenant_member | guest). guest 는 internet 앱에 로그인한 비멤버. omitempty — handler 가 채울 수 있을 때만 직렬화 (Me / ListMine 만 채움; Grant 직후엔 빈 값). |
createdAt (wire: created_at) | string | CreatedAt 은 row 생성 시각 (UTC). |
grantedAt (wire: granted_at) | string | GrantedAt 은 grant 시각 (UTC). |
grantedById (wire: granted_by_id) | string | GrantedByID 는 권한을 부여한 주체 (admin 또는 self) UUID. self-grant 면 omit 가능. |
id | string | ID 는 access 행 UUID. |
isAdmin (wire: is_admin) | boolean | IsAdmin — caller 가 owner / tenant_admin / platform_admin 중 하나인지. X-AxHub-Is-Admin 헤더와 동일 의미. |
updatedAt (wire: updated_at) | string | UpdatedAt 은 row 마지막 수정 시각 (UTC). |
userId (wire: user_id) | string | UserID 는 받은 사용자 UUID. |
Error statuses: 400 401 403 404 409 500 — Error handling
GET /api/v1/apps/{appID}/access/me
appsGetApiV1AppsByAppIDAccessMe
현재 사용자가 특정 앱에 부여받은 access 를 반환한다 (받은 적이 없으면 404).
- 호출 권한: 인증된 사용자 (본인 access 만 조회).
- app_id 가 UUID 형식이 아니면 400.
- 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps.access(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1AppsByAppIDAccessMe(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1AppsByAppIDAccessMe(pathParams, query, body) — async: appsGetApiV1AppsByAppIDAccessMeAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1AppsByAppIDAccessMe(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_apps_by_app_id_access_me(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_apps_by_app_id_access_me(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1AppsByAppIDAccessMe", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 200 · 내 access
| Name | Type | Description |
|---|---|---|
allowedScopes (wire: allowed_scopes) | array<string> | AllowedScopes 는 허용된 scope 문자열 (예: data.read, data.write). |
app | any | App 은 access 대상 앱의 inline 요약 (name / icon / access_url 등). GET /users/me/apps (ListMine) 응답에서만 batch enrich 로 채워짐 — FE 가 "내 업무공간" 카드를 row 마다 단건 GET 없이 그릴 수 있게. Me / Grant / Invite 응답에선 omit. fetch 실패 / permanently_deleted 면 omit. |
appId (wire: app_id) | string | AppID 는 대상 앱 UUID. |
appRole (wire: app_role) | string | AppRole — caller 의 L2 gate 효과적 역할 (CLI gap G-P3-006). 값은 appdomain.DeriveAppRole 의 6-enum (owner | platform_admin | tenant_admin | app_member | tenant_member | guest). guest 는 internet 앱에 로그인한 비멤버. omitempty — handler 가 채울 수 있을 때만 직렬화 (Me / ListMine 만 채움; Grant 직후엔 빈 값). |
createdAt (wire: created_at) | string | CreatedAt 은 row 생성 시각 (UTC). |
grantedAt (wire: granted_at) | string | GrantedAt 은 grant 시각 (UTC). |
grantedById (wire: granted_by_id) | string | GrantedByID 는 권한을 부여한 주체 (admin 또는 self) UUID. self-grant 면 omit 가능. |
id | string | ID 는 access 행 UUID. |
isAdmin (wire: is_admin) | boolean | IsAdmin — caller 가 owner / tenant_admin / platform_admin 중 하나인지. X-AxHub-Is-Admin 헤더와 동일 의미. |
updatedAt (wire: updated_at) | string | UpdatedAt 은 row 마지막 수정 시각 (UTC). |
userId (wire: user_id) | string | UserID 는 받은 사용자 UUID. |
Error statuses: 400 401 404 500 — Error handling
POST /api/v1/apps/{appID}/archive
appsPostApiV1AppsByAppIDArchive
앱을 보관해 스토어/검색에서 숨긴다 (참고용으로 보존). status 를 archived 로 전이.
- 호출 권한: 앱 소유자 / 같은 테넌트의 tenant_admin / platform_admin (gate
RequireAppOwnerOrAdmin). - 입력: appID (path). body 없음.
- 호출 조건: archived 가 아닌 모든 상태(draft/deployed/suspended)에서 가능. 이미 archived 면 멱등(no-op 200).
- 부수 효과: status=archived. suspended 앱을 보관하면 suspended_at 은 그대로 보존(과거 일시정지 시각 기록).
| Language | Call |
|---|---|
| node | not provided |
| go | client.Apps.AppsPostApiV1AppsByAppIDArchive(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsPostApiV1AppsByAppIDArchive(pathParams, query, body) — async: appsPostApiV1AppsByAppIDArchiveAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsPostApiV1AppsByAppIDArchive(pathParams, query, body) — suspend |
| python | client.apps.apps_post_api_v1_apps_by_app_id_archive(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_post_api_v1_apps_by_app_id_archive(path_params: …, query: …, body: …) |
| generic | request("appsPostApiV1AppsByAppIDArchive", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 200 · 보관된 앱 (status=archived)
| Name | Type | Description |
|---|---|---|
accessUrl (wire: access_url) | string | AccessURL 은 앱의 접속 URL (https://{subdomain}.{tenant_slug}.{base_domain}). subdomain 미설정 앱은 null — FE 는 앱 상세로 fallback. list (Search / List / Discover / users/me/apps embed) 와 단건 (Get) 응답에서 batch enrich 로 채워짐. Create 응답은 항상 null (subdomain 유무와 무관하게 생성 직후엔 enrich 안 함). |
authMode (wire: auth_mode) | string | AuthMode 는 앱 dataapi 가 받는 대표 인증 방식. 가능값: cookie / bearer / api_key / anonymous. 기본 bearer. |
callsCount (wire: calls_count) | integer | CallsCount 는 누적 dataapi 호출 수. denormalized counter — v1 에선 갱신 로직 없이 항상 0; 미래 phase 에서 gateway_log projection 이 채움. |
category | any | Category 는 앱 카테고리의 inline 표현. 단건 조회와 list 응답 (Search / List / Discover) 모두에서 batch enrich 로 채워짐. 카테고리가 없거나 missing 이면 필드 자체가 omit. AppsCount 는 enrich 시 0 (이 컨텍스트에서 카테고리 자체의 분포는 의미 없음). |
categoryId (wire: category_id) | string | CategoryID 는 카테고리 UUID. 카테고리가 없으면 omit. |
costCenter (wire: cost_center) | string | CostCenter 는 비용 귀속 라벨 (팀/부서). null = 미할당 (spec 003). |
createdAt (wire: created_at) | string | CreatedAt 은 생성 시각 (UTC). |
dataScopes (wire: data_scopes) | array<string> | DataScopes 는 앱이 노출하는 dataapi scope 라벨 목록. 자유 형식. 빈 배열이면 scope 정의 없음 — handler 가 scope 검사 안 함. |
deletedAt (wire: deleted_at) | string | DeletedAt 은 soft-delete 시각 (UTC). 살아있는 앱이면 omit. |
deployMethod (wire: deploy_method) | string | DeployMethod is the immutable deployment strategy: docker / compose / static. |
description | string | Description 은 앱 설명 (선택, 최대 20000자). |
iconDarkUrl (wire: icon_dark_url) | string | IconDarkURL 은 다크 모드용 아이콘 URL (선택). 없으면 FE 가 IconURL 로 fallback. |
iconUrl (wire: icon_url) | string | IconURL 은 아이콘 이미지 URL (선택, 라이트 모드용). |
id | string | ID 는 앱 UUID. |
lastDeploymentStatus (wire: last_deployment_status) | string | LastDeploymentStatus 는 가장 최근 deployment 의 raw 도메인 상태. 가능값: pending / running (배포 진행 중) / succeeded (라이브) / failed / cancelled. deployment 가 한 번도 없는 앱 (예: 방금 생성된 draft) 은 null. POST /apps (Create) 응답은 항상 null — 생성 직후엔 deployment 가 없음. List/Get/Search/PATCH 응답은 모두 enrich 된 값. 주의: backend enum 의 running 은 "배포 작업 진행 중" 이고 succeeded 가 "앱이 라이브 (운영중)" 다. FE 매핑 시 둘 혼동 X. |
likeCount (wire: like_count) | integer | LikeCount 는 좋아요 누적 수. |
name | string | Name 은 사람이 읽는 표시 이름. |
operatingStatus (wire: operating_status) | string | OperatingStatus 는 운영 상태 rollup. archived (보관됨) / live (운영중) / dev (개발중). status·review_status·visibility 에서 파생된 요약일 뿐 — 위 raw 필드들은 그대로 응답에 남아 이 rollup 이 다른 상태를 가리지 않는다. archived → status archived (최우선) live → review_status approved + visibility invite_only/public/internet dev → 그 외 (심사 전/대기/반려, 또는 승인됐지만 private) |
owner | any | Owner 는 앱 owner 의 inline 요약 (이름·아바타). 단건 조회 (GET /api/v1/apps/{appID}) 와 list 응답 (Search / List / Discover) 모두에서 batch enrich 로 채워짐 — FE 가 row 마다 단건 GET 을 부르는 N+1 을 피하기 위함. owner_id 가 가리키는 사용자가 missing/soft-deleted 면 필드 자체가 omit. |
ownerId (wire: owner_id) | string | OwnerID 는 앱 소유자 (생성자) 의 사용자 UUID. |
productionDeploymentId (wire: production_deployment_id) | string | ProductionDeploymentID 는 지금 prod 가 서빙 중인 deployment UUID. 성공 배포가 한 번도 없으면 null. 버전 번호는 releases API 에서 조회. |
resourcePreset (wire: resource_preset) | string | ResourcePreset 는 Resources 값을 카탈로그와 매칭한 파생 라벨 (XS/S/M/L/XL 또는 커스텀). 저장하지 않고 매번 계산. (spec 014) |
resources | any | Resources 는 Pod CPU/메모리 사양 (저장된 값 4개). (spec 014) |
resumedAt (wire: resumed_at) | string | ResumedAt 은 마지막 resume 시각 (UTC, spec 312). 한 번도 suspend 한 적 없으면 omit. 현재 suspended_at != nil 이어도 옛 resume 이력이 있으면 값이 남아있을 수 있음 (이력 용도). |
reviewStatus (wire: review_status) | string | ReviewStatus 는 심사 상태. not_submitted / pending / approved / rejected. |
schemaName (wire: schema_name) | string | SchemaName 은 앱 전용 Postgres schema 이름. 생성 시 자동 발급. |
sharedTablesCount (wire: shared_tables_count) | integer | SharedTablesCount 는 이 앱이 다른 앱에 grant 한 dynamic_table 수. denormalized counter — v1 에선 항상 0; 미래 phase 에서 table_grant projection 이 채움. |
slug | string | Slug 는 URL 식별자. [a-z0-9-]+. 같은 테넌트 안 unique. |
stagingDeploymentId (wire: staging_deployment_id) | string | StagingDeploymentID 는 지금 staging 이 서빙 중인 deployment UUID. 옵트인 안 했거나 staging 배포 전이면 null. |
stagingEnabled (wire: staging_enabled) | boolean | StagingEnabled 는 스테이징 옵트인 여부 (spec 016). true 면 push 가 staging 에만 반영되고 prod 는 promote(심사 승인)로만 바뀜. staging URL 은 access_url 의 subdomain 에 --staging 을 붙인 호스트. |
status | string | Status 는 앱 배포 상태 (spec 324). draft (배포 전) / deployed (배포됨) / archived (보관됨). 배포 성공 시 draft→deployed 자동 전이. soft-delete 여부는 별 deleted_at, 최근 배포 attempt 의 raw 상태는 별 last_deployment_status. |
subdomain | string | Subdomain 은 접속 주소 (선택, 2~32자 소문자/숫자/하이픈). 미설정 상태면 omit — 다음 deploy 시 412 까지 deploy 못 함. |
subscriberCount (wire: subscriber_count) | integer | SubscriberCount 는 앱을 "받은" (UserAppAccess grant) 사용자 수. |
summary | string | Summary 는 앱의 "한 줄 소개" (선택, 최대 60자). description(상세 설명) 과 분리된 짧은 소개. 미설정이면 omit. |
suspendedAt (wire: suspended_at) | string | SuspendedAt 은 runtime suspend 시각 (UTC, spec 312). non-nil 이면 K8s namespace 가 정리된 상태 (pod 0). status 와 직교 — 어느 lifecycle 단계든 suspend 가능. live 상태면 omit. |
tenantId (wire: tenant_id) | string | TenantID 는 앱이 속한 테넌트 UUID. |
updatedAt (wire: updated_at) | string | UpdatedAt 은 마지막 수정 시각 (UTC). |
visibility | string | Visibility 는 카탈로그 노출 범위. private / invite_only / public / internet(익명 포함 인터넷 전체). |
Error statuses: 400 401 403 404 500 — Error handling
PATCH /api/v1/apps/{appID}/browse-policy
appsPatchApiV1AppsByAppIDBrowsePolicy
콘솔 리소스 내용 열람(raw DB 행·스토리지 파일·환경변수 값) 정책을 바꾼다 (spec 174).
- 호출 권한: 소유자군만 (대표 owner 또는 co-owner — tenant_admin·platform_admin 도 불가, usecase 판정. 라우트 게이트는 RequireAuth 만).
- 정책 값:
open(기본 — 현행 그대로) /owners_only(소유자군 외 전원 차단 — 관리자 포함, break-glass 없음) /locked(소유자군까지 차단). 차단돼도 테이블 목록·컬럼 구조·저장 용량·환경변수 키 이름은 계속 보인다. locked상태에서도 소유자군의 이 표면 접근·해제는 항상 가능 (해제 불능 잠금 금지).- 같은 값 재설정은 멱등 200 (감사·통지 생략).
- 부수 효과: hash-chain 감사
app_browse_policy_changeemit-first (실패 시 변경 중단) + 소유자군 전원 알림함 통지 (best-effort). - spec 174 신규 표면 — SDK 릴리스에 순차 반영 중 (미포함 버전에서는 아래 이름의 메서드가 아직 없다).
| Language | Call |
|---|---|
| node | not provided |
| go | client.Apps.AppsPatchApiV1AppsByAppIDBrowsePolicy(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsPatchApiV1AppsByAppIDBrowsePolicy(pathParams, query, body) — async: appsPatchApiV1AppsByAppIDBrowsePolicyAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsPatchApiV1AppsByAppIDBrowsePolicy(pathParams, query, body) — suspend |
| python | client.apps.apps_patch_api_v1_apps_by_app_id_browse_policy(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_patch_api_v1_apps_by_app_id_browse_policy(path_params: …, query: …, body: …) |
| generic | request("appsPatchApiV1AppsByAppIDBrowsePolicy", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Request body — pass via body, wire keys (snake_case) as-is
| Name | Type | Description |
|---|---|---|
browse_policy required | string | 목표 정책: open / owners_only / locked |
Response — 200 · 반영된 정책
| Name | Type | Description |
|---|---|---|
browsePolicy (wire: browse_policy) | string | 현재(반영 후) 정책 값 |
Error statuses: 400 401 403 404 500 — Error handling
GET /api/v1/apps/{appID}/comments
appsGetApiV1AppsByAppIDComments
특정 앱의 댓글 목록을 작성 시각 순으로 반환한다.
- 호출 권한: 인증된 사용자.
- app_id 가 UUID 형식이 아니면 400.
- 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps.comments(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1AppsByAppIDComments(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1AppsByAppIDComments(pathParams, query, body) — async: appsGetApiV1AppsByAppIDCommentsAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1AppsByAppIDComments(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_apps_by_app_id_comments(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_apps_by_app_id_comments(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1AppsByAppIDComments", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 200 · 댓글 목록
| Name | Type | Description |
|---|---|---|
items | array<object> | |
nextCursor (wire: next_cursor) | string | |
total | integer |
Error statuses: 400 401 500 — Error handling
POST /api/v1/apps/{appID}/comments
appsPostApiV1AppsByAppIDComments
특정 앱에 댓글을 작성한다.
- 호출 권한: 인증된 사용자 (visibility 가 차단하지 않는 한).
- 본문은 1~500자. 위반 시 400.
- app_id 가 UUID 형식이 아니면 400.
- 부수 효과 없음.
| Language | Call |
|---|---|
| node | sdk.apps.comments(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsPostApiV1AppsByAppIDComments(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsPostApiV1AppsByAppIDComments(pathParams, query, body) — async: appsPostApiV1AppsByAppIDCommentsAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsPostApiV1AppsByAppIDComments(pathParams, query, body) — suspend |
| python | client.apps.apps_post_api_v1_apps_by_app_id_comments(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_post_api_v1_apps_by_app_id_comments(path_params: …, query: …, body: …) |
| generic | request("appsPostApiV1AppsByAppIDComments", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Request body — pass via body, wire keys (snake_case) as-is
| Name | Type | Description |
|---|---|---|
body | string | Body 는 댓글 내용. 1~500자. |
Response — 201 · 작성된 댓글
| Name | Type | Description |
|---|---|---|
appId (wire: app_id) | string | AppID 는 댓글이 달린 앱 UUID. |
body | string | Body 는 댓글 내용. 1~500자. |
createdAt (wire: created_at) | string | CreatedAt 은 작성 시각 (UTC). |
id | string | ID 는 댓글 UUID. |
updatedAt (wire: updated_at) | string | UpdatedAt 은 마지막 수정 시각 (UTC). |
user | any | User 는 댓글 작성자의 inline 요약 (이름·아바타). 목록 조회 (GET /api/v1/apps/{appID}/comments) 가 user_id 들을 batch 로 모아 Identity 에 한 번 묻는다. missing/soft-deleted 면 omit — 호출자는 기존 user_id UUID 로 fallback. |
userId (wire: user_id) | string | UserID 는 댓글 작성자 UUID. |
Error statuses: 400 401 404 500 — Error handling
GET /api/v1/apps/{appID}/env-vars
appsGetApiV1AppsByAppIDEnvVars
특정 앱의 환경변수 목록을 반환한다.
- 호출 권한: 앱 소유자 / 같은 테넌트의 admin / platform admin (
RequireAppOwnerOrAdmin— 아니면 403). secret=true인 항목은 value 가***로 마스킹.- 각 항목의
stage는 주입 통로 (build/runtime/both). - 부수 효과 없음 (read-only — secret 은 캐시된 평문에서 마스킹).
| Language | Call |
|---|---|
| node | sdk.apps.listEnvVars(…) — 리소스 모델 — 인자·반환 타입은 패키지의 TypeScript 정의 참조 |
| go | client.Apps.AppsGetApiV1AppsByAppIDEnvVars(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1AppsByAppIDEnvVars(pathParams, query, body) — async: appsGetApiV1AppsByAppIDEnvVarsAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1AppsByAppIDEnvVars(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_apps_by_app_id_env_vars(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_apps_by_app_id_env_vars(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1AppsByAppIDEnvVars", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 200 · 환경변수 목록
Array response → the SDK wraps it as {"value": [...]}. Element fields:
| Name | Type | Description |
|---|---|---|
hasStagingOverride (wire: has_staging_override) | boolean | HasStagingOverride 는 staging 전용 override 존재 여부 (spec 016 FR-016). 값은 노출하지 않음 — 해제는 PUT .../staging-value 에 null. |
key | string | Key 는 환경변수 이름. |
secret | boolean | Secret 는 secret 여부. |
stage | string | Stage 는 주입 통로 (build / runtime / both). |
value | string | Value 는 환경변수 값. secret=true 면 *** 로 마스킹. |
Error statuses: 400 401 403 500 — Error handling
POST /api/v1/apps/{appID}/env-vars
appsPostApiV1AppsByAppIDEnvVars
앱의 환경변수를 생성하거나 갱신한다. 같은 key 가 있으면 value/secret/stage 모두 덮어씀.
- 호출 권한: 앱 소유자 / 같은 테넌트의 admin / platform admin (
RequireAppOwnerOrAdmin— 아니면 403). - key 는
[A-Z][A-Z0-9_]*패턴 (대문자/숫자/_, 첫 글자는 대문자). 위반 시 400 (ErrInvalidKey). - value 빈 문자열 불가 (ErrEmptyValue → 400).
- stage 는
build/runtime/both중 하나. 생략하면runtime. 그 외 값은 400 (ErrInvalidStage). 다음 배포 시 build-arg / 런타임 env 통로가 stage 에 따라 갈림. - 부수 효과: DB 에 평문 또는 암호화된 값 저장. 응답의 value 는 secret=true 면
***로 마스킹.
| Language | Call |
|---|---|
| node | sdk.apps.setEnvVar(…) — 리소스 모델 — 인자·반환 타입은 패키지의 TypeScript 정의 참조 |
| go | client.Apps.AppsPostApiV1AppsByAppIDEnvVars(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsPostApiV1AppsByAppIDEnvVars(pathParams, query, body) — async: appsPostApiV1AppsByAppIDEnvVarsAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsPostApiV1AppsByAppIDEnvVars(pathParams, query, body) — suspend |
| python | client.apps.apps_post_api_v1_apps_by_app_id_env_vars(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_post_api_v1_apps_by_app_id_env_vars(path_params: …, query: …, body: …) |
| generic | request("appsPostApiV1AppsByAppIDEnvVars", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Request body — pass via body, wire keys (snake_case) as-is
| Name | Type | Description |
|---|---|---|
key | string | Key 는 환경변수 이름. 대문자/숫자/_ 만, 첫 글자는 대문자. (예: DATABASE_URL) |
secret | boolean | Secret 가 true 면 값이 마스킹되어 응답에 노출 (***) 되고 DB 에 암호화 저장. |
stage | string | Stage 는 주입 통로. build (빌드 build-arg 만) / runtime (런타임 env 만) / both (양쪽). 생략하면 runtime. 잘못된 값은 400. |
value | string | Value 는 환경변수 값. 빈 문자열 불가. |
Response — 200 · 저장된 환경변수 (secret 은 마스킹)
| Name | Type | Description |
|---|---|---|
hasStagingOverride (wire: has_staging_override) | boolean | HasStagingOverride 는 staging 전용 override 존재 여부 (spec 016 FR-016). 값은 노출하지 않음 — 해제는 PUT .../staging-value 에 null. |
key | string | Key 는 환경변수 이름. |
secret | boolean | Secret 는 secret 여부. |
stage | string | Stage 는 주입 통로 (build / runtime / both). |
value | string | Value 는 환경변수 값. secret=true 면 *** 로 마스킹. |
Error statuses: 400 401 403 500 — Error handling
PUT /api/v1/apps/{appID}/env-vars/{key}/staging-value
appsPutApiV1AppsByAppIDEnvVarsByKeyStagingValue
키의 staging 전용 값을 설정/해제한다 (spec 016 FR-016). null = override 해제(prod 값 상속).
- 호출 권한: app owner | tenant_admin (기존 env-vars gate 와 동일)
- build stage 키는 환경별 값 불가 (FR-017 — 이미지가 promote 로 그대로 승격되므로)
- 부수 효과: 다음 staging 배포부터 적용 (즉시 재시작 없음)
| Language | Call |
|---|---|
| node | sdk.apps.setStagingValue(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsPutApiV1AppsByAppIDEnvVarsByKeyStagingValue(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsPutApiV1AppsByAppIDEnvVarsByKeyStagingValue(pathParams, query, body) — async: appsPutApiV1AppsByAppIDEnvVarsByKeyStagingValueAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsPutApiV1AppsByAppIDEnvVarsByKeyStagingValue(pathParams, query, body) — suspend |
| python | client.apps.apps_put_api_v1_apps_by_app_id_env_vars_by_key_staging_value(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_put_api_v1_apps_by_app_id_env_vars_by_key_staging_value(path_params: …, query: …, body: …) |
| generic | request("appsPutApiV1AppsByAppIDEnvVarsByKeyStagingValue", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
key required | string | 환경변수 키 |
Request body — pass via body, wire keys (snake_case) as-is
| Name | Type | Description |
|---|---|---|
value | string | Value 는 staging 에서만 쓰일 평문 값. null 이면 override 해제 (prod 값 상속). |
Response — 204 · 적용 완료
No body → the SDK returns an empty map {}
Error statuses: 400 401 403 404 500 — Error handling
DELETE /api/v1/apps/{appID}/likes
appsDeleteApiV1AppsByAppIDLikes
현재 사용자가 특정 앱의 좋아요를 취소한다. 안 누른 상태여도 204 (idempotent).
- 호출 권한: 인증된 사용자.
- app_id 가 UUID 형식이 아니면 400.
- 부수 효과: 앱의
like_count감소 (좋아요 안 한 상태면 변화 0).
| Language | Call |
|---|---|
| node | sdk.apps.likes(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsDeleteApiV1AppsByAppIDLikes(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsDeleteApiV1AppsByAppIDLikes(pathParams, query, body) — async: appsDeleteApiV1AppsByAppIDLikesAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsDeleteApiV1AppsByAppIDLikes(pathParams, query, body) — suspend |
| python | client.apps.apps_delete_api_v1_apps_by_app_id_likes(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_delete_api_v1_apps_by_app_id_likes(path_params: …, query: …, body: …) |
| generic | request("appsDeleteApiV1AppsByAppIDLikes", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 204 · 취소 성공 (no content)
No body → the SDK returns an empty map {}
Error statuses: 400 401 404 500 — Error handling
POST /api/v1/apps/{appID}/likes
appsPostApiV1AppsByAppIDLikes
현재 사용자가 특정 앱을 좋아요 한다. 이미 누른 상태면 그대로 200 (idempotent).
- 호출 권한: 인증된 사용자.
- app_id 가 UUID 형식이 아니면 400.
- 부수 효과: 앱의
like_count증가 (이미 좋아요 한 상태면 변화 0).
| Language | Call |
|---|---|
| node | sdk.apps.likes(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsPostApiV1AppsByAppIDLikes(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsPostApiV1AppsByAppIDLikes(pathParams, query, body) — async: appsPostApiV1AppsByAppIDLikesAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsPostApiV1AppsByAppIDLikes(pathParams, query, body) — suspend |
| python | client.apps.apps_post_api_v1_apps_by_app_id_likes(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_post_api_v1_apps_by_app_id_likes(path_params: …, query: …, body: …) |
| generic | request("appsPostApiV1AppsByAppIDLikes", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 200 · 좋아요 결과 (liked=true)
| Name | Type | Description |
|---|---|---|
liked | boolean | Liked 는 현재 사용자가 이 앱을 좋아요 했는지 여부. |
Error statuses: 400 401 404 500 — Error handling
GET /api/v1/apps/{appID}/likes/me
appsGetApiV1AppsByAppIDLikesMe
현재 사용자가 특정 앱을 좋아요 했는지 여부를 반환한다.
- 호출 권한: 인증된 사용자.
- app_id 가 UUID 형식이 아니면 400.
- 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps.likes(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1AppsByAppIDLikesMe(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1AppsByAppIDLikesMe(pathParams, query, body) — async: appsGetApiV1AppsByAppIDLikesMeAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1AppsByAppIDLikesMe(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_apps_by_app_id_likes_me(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_apps_by_app_id_likes_me(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1AppsByAppIDLikesMe", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 200 · 현재 좋아요 여부
| Name | Type | Description |
|---|---|---|
liked | boolean | Liked 는 현재 사용자가 이 앱을 좋아요 했는지 여부. |
Error statuses: 400 401 500 — Error handling
DELETE /api/v1/apps/{appID}/raw-db
appsDeleteApiV1AppsByAppIDRawDb
raw DB 모드를 끄고 전용 role 의 접근을 차단한다. 앱 데이터(schema·테이블)는 보존된다 — 재활성 시 새 비밀번호가 발급된다.
- 호출 권한: 앱 소유자 / 같은 테넌트의 tenant_admin / platform_admin (gate
RequireAppOwnerOrAdmin). - 입력: appID (path). body 없음.
- 멱등: 이미 꺼져 있으면 204.
- 부수 효과: PG role 을 NOLOGIN 으로 전환 + Secret Manager 비밀번호 삭제. 데이터는 삭제하지 않는다.
| Language | Call |
|---|---|
| node | sdk.apps.rawDb.disable(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsDeleteApiV1AppsByAppIDRawDb(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsDeleteApiV1AppsByAppIDRawDb(pathParams, query, body) — async: appsDeleteApiV1AppsByAppIDRawDbAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsDeleteApiV1AppsByAppIDRawDb(pathParams, query, body) — suspend |
| python | client.apps.apps_delete_api_v1_apps_by_app_id_raw_db(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_delete_api_v1_apps_by_app_id_raw_db(path_params: …, query: …, body: …) |
| generic | request("appsDeleteApiV1AppsByAppIDRawDb", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 204 · raw DB 비활성화됨 (본문 없음)
No body → the SDK returns an empty map {}
Error statuses: 400 401 403 404 500 — Error handling
POST /api/v1/apps/{appID}/raw-db
appsPostApiV1AppsByAppIDRawDb
앱에 전용 Postgres role 을 발급하고 raw DB 모드를 켠다. 다음 배포부터 표준 DATABASE_URL(+마이그레이션용 DIRECT_DATABASE_URL)이 컨테이너에 주입돼, 앱이 우리 동적 DB(/data) 없이 자기 데이터를 평범한 Postgres 처럼 쓴다.
- 호출 권한: 앱 소유자 / 같은 테넌트의 tenant_admin / platform_admin (gate
RequireAppOwnerOrAdmin). - 입력: appID (path). body 없음.
- 멱등: 이미 켜져 있으면 비밀번호를 회전하지 않고 그대로 200.
- 부수 효과: 전용 PG role 생성 + 자기 schema 에만 GRANT + 비밀번호를 Secret Manager 에 저장. 연결 문자열은 응답에 노출되지 않고 배포 시 주입된다.
| Language | Call |
|---|---|
| node | sdk.apps.rawDb.enable(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsPostApiV1AppsByAppIDRawDb(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsPostApiV1AppsByAppIDRawDb(pathParams, query, body) — async: appsPostApiV1AppsByAppIDRawDbAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsPostApiV1AppsByAppIDRawDb(pathParams, query, body) — suspend |
| python | client.apps.apps_post_api_v1_apps_by_app_id_raw_db(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_post_api_v1_apps_by_app_id_raw_db(path_params: …, query: …, body: …) |
| generic | request("appsPostApiV1AppsByAppIDRawDb", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Response — 200 · raw DB 활성 상태
| Name | Type | Description |
|---|---|---|
injectedOnNextDeploy (wire: injected_on_next_deploy) | boolean | InjectedOnNextDeploy 는 DATABASE_URL 이 다음 배포 때 주입됨을 알린다. |
rawDbEnabled (wire: raw_db_enabled) | boolean | RawDBEnabled 은 현재 raw DB 모드 활성 여부. |
Error statuses: 400 401 403 404 409 500 — Error handling
GET /api/v1/apps/{appID}/resource-access-logs
appsGetApiV1AppsByAppIDResourceAccessLogs
콘솔 내용 열람(raw DB 행·스토리지 파일·환경변수 값)의 기록을 최신순으로 반환한다 (spec 174).
- 호출 권한: app owner 또는 tenant_admin (
RequireAppOwnerOrAdmin— platform_admin 포함). 기록은 메타데이터라 관리자 열람 허용이 억지력의 일부. - 내용 열람 호출 1번 = 기록 1행 (다운로드는 파일별). 차단된 시도(
result=blocked)도 포함. - 정책 변경 이력은 포함하지 않는다 (감사 원장 소관).
- 부수 효과 없음 (read-only — 이 조회 자체는 기록되지 않는다).
- spec 174 신규 표면 — SDK 릴리스에 순차 반영 중 (미포함 버전에서는 아래 이름의 메서드가 아직 없다).
| Language | Call |
|---|---|
| node | not provided |
| go | client.Apps.AppsGetApiV1AppsByAppIDResourceAccessLogs(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1AppsByAppIDResourceAccessLogs(pathParams, query, body) — async: appsGetApiV1AppsByAppIDResourceAccessLogsAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1AppsByAppIDResourceAccessLogs(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_apps_by_app_id_resource_access_logs(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_apps_by_app_id_resource_access_logs(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1AppsByAppIDResourceAccessLogs", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
appID required | string | 앱 UUID |
Query parameters — pass via query (string values)
| Name | Type | Description |
|---|---|---|
axis | string | 자원 축 필터 (table|storage|env) |
user_id | string | 열람자 필터 (UUID) |
from | string | 기간 시작 (RFC3339, last_at 기준) |
to | string | 기간 끝 (RFC3339, last_at 기준) |
page | integer | 페이지 (1-base, 기본 1) |
per_page | integer | 페이지당 행 수 (기본 50, 최대 200) |
Response — 200 · 열람 기록 한 페이지 (last_at DESC)
Paginated response { items: [...], total, next_cursor } — items element fields:
| Name | Type | Description |
|---|---|---|
axis | string | Axis 는 자원 축: table / storage / env. |
firstAt (wire: first_at) | string | FirstAt 은 열람 시각 (UTC) — 건별 기록이라 LastAt 과 동일. |
id | string | ID 는 기록 행 UUID. |
lastAt (wire: last_at) | string | LastAt 은 열람 시각 (UTC). 정렬 키 — 건별 기록이라 FirstAt 과 동일. |
pageCount (wire: page_count) | integer | PageCount 는 항상 1 (호출 1번 = 행 1개 — 하위호환용 필드). |
result | string | Result 는 viewed(열람) / blocked(시도 → 차단). |
target | string | Target 은 축별 대상 — 테이블명 / 파일 키 / ""(env·목록). |
userEmail (wire: user_email) | string | UserEmail 은 열람자 이메일 (enrich 실패 시 생략). |
userId (wire: user_id) | string | UserID 는 열람자 UUID. |
userName (wire: user_name) | string | UserName 은 열람자 표시 이름 (enrich 실패 시 생략). |
Error statuses: 400 401 403 404 500 — Error handling
DELETE /api/v1/comments/{commentID}
appsDeleteApiV1CommentsByCommentID
댓글을 삭제한다.
- 호출 권한: 본인이 작성한 댓글 또는 platform admin (이외 → 403 ErrDeleteForbidden).
- 이미 삭제된 댓글이면 409 (ErrAlreadyDeleted).
- 부수 효과 없음.
| Language | Call |
|---|---|
| node | sdk.apps.comments(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsDeleteApiV1CommentsByCommentID(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsDeleteApiV1CommentsByCommentID(pathParams, query, body) — async: appsDeleteApiV1CommentsByCommentIDAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsDeleteApiV1CommentsByCommentID(pathParams, query, body) — suspend |
| python | client.apps.apps_delete_api_v1_comments_by_comment_id(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_delete_api_v1_comments_by_comment_id(path_params: …, query: …, body: …) |
| generic | request("appsDeleteApiV1CommentsByCommentID", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
commentID required | string | 댓글 UUID |
Response — 204 · 삭제 성공 (no content)
No body → the SDK returns an empty map {}
Error statuses: 400 401 403 404 409 500 — Error handling
GET /api/v1/me/apps/owned
appsGetApiV1MeAppsOwned
현재 사용자가 owner_id 인 앱을 cross-tenant 로 반환한다.
- 호출 권한: 인증된 사용자 (본인 owner 앱만).
- 필터 없음 (모든 status / visibility 다 포함). 호출자가 own 한 모든 라이프사이클 단계의 앱 자체가 시그널.
- 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps.me/listMine(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1MeAppsOwned(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1MeAppsOwned(pathParams, query, body) — async: appsGetApiV1MeAppsOwnedAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1MeAppsOwned(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_me_apps_owned(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_me_apps_owned(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1MeAppsOwned", pathParams, query, body) |
Response — 200 · 내가 만든 앱 목록
| Name | Type | Description |
|---|---|---|
items | array<object> | |
nextCursor (wire: next_cursor) | string | |
total | integer |
Error statuses: 401 500 — Error handling
GET /api/v1/me/apps/received
appsGetApiV1MeAppsReceived
현재 사용자가 user_app_accesses 행으로 받은 앱 목록 (owner 인 앱은 제외 — 그건 /me/apps/owned).
- 호출 권한: 인증된 사용자 (본인 access 행만).
- 응답 shape 는 owned / workspace 와 동일한 appResponse — UI 카드 렌더링 일관성.
- 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps.me/listMine(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1MeAppsReceived(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1MeAppsReceived(pathParams, query, body) — async: appsGetApiV1MeAppsReceivedAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1MeAppsReceived(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_me_apps_received(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_me_apps_received(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1MeAppsReceived", pathParams, query, body) |
Response — 200 · 내가 받은 앱 목록
| Name | Type | Description |
|---|---|---|
items | array<object> | |
nextCursor (wire: next_cursor) | string | |
total | integer |
Error statuses: 401 500 — Error handling
GET /api/v1/me/apps/workspace
appsGetApiV1MeAppsWorkspace
현재 사용자가 owner 이거나 invite 로 받은 앱의 union, de-duplicated.
- 호출 권한: 인증된 사용자.
- 같은 앱을 owner 이자 invite 로도 갖고 있으면 한 번만 반환됨.
- 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps.me/listMine(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1MeAppsWorkspace(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1MeAppsWorkspace(pathParams, query, body) — async: appsGetApiV1MeAppsWorkspaceAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1MeAppsWorkspace(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_me_apps_workspace(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_me_apps_workspace(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1MeAppsWorkspace", pathParams, query, body) |
Response — 200 · 내 작업 공간 앱 목록
| Name | Type | Description |
|---|---|---|
items | array<object> | |
nextCursor (wire: next_cursor) | string | |
total | integer |
Error statuses: 401 500 — Error handling
GET /api/v1/templates
appsGetApiV1Templates
앱 생성 화면이 호출하는 카탈로그. active=true 인 템플릿만 반환 (sort_order ASC).
- 호출 권한: 로그인된 사용자 (RequireAuth).
- 입력 없음.
- 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps.templates(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1Templates(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1Templates(pathParams, query, body) — async: appsGetApiV1TemplatesAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1Templates(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_templates(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_templates(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1Templates", pathParams, query, body) |
Response — 200 · 활성 템플릿 목록
| Name | Type | Description |
|---|---|---|
items | array<object> | |
nextCursor (wire: next_cursor) | string | |
total | integer |
Error statuses: 401 500 — Error handling
GET /api/v1/tenants/{tenantID}/apps
appsGetApiV1TenantsByTenantIDApps
특정 테넌트가 소유한 모든 앱 목록을 반환한다 (owner·visibility 무관, soft-deleted 제외).
- 호출 권한: path 의 테넌트에 active 멤버십이 있는 사용자만 (platform_admin 은 자동 통과). 비멤버 → 403.
- path 의 tenantID 가 UUID 형식이 아니면 400.
- 검색:
q는 이름·slug·설명·카테고리명에 pg_trgm 유사도 매칭 (있으면 유사도 우선 정렬). - status 필터는
draft/deployed/archived. 4 표기 지원 (status,status_inCSV,filter[status],filter[status][]). multi-value 는 OR. - review_status 필터는
not_submitted/pending/approved/rejected. 동일하게 4 표기 + multi OR. - operating_status 필터는 운영 상태 rollup
live(운영중) /dev(개발중) /archived(보관됨). 동일하게 4 표기 + multi OR. status·review_status·visibility 에서 파생 —dev는 미승인 OR (승인+private) 의 OR 조건을 서버가 SQL 로 해소 (live는 approved + invite_only/public/internet). category_id로 카테고리 필터.sort는-created_at(기본) /-like_count/-subscriber_count/ name.- 페이징:
page(1-base) +per_page(또는limit, 최대 200). 응답total은 필터 적용 후 전체 건수. - 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps.create/list(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1TenantsByTenantIDApps(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1TenantsByTenantIDApps(pathParams, query, body) — async: appsGetApiV1TenantsByTenantIDAppsAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1TenantsByTenantIDApps(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_tenants_by_tenant_id_apps(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_tenants_by_tenant_id_apps(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1TenantsByTenantIDApps", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
tenantID required | string | 테넌트 UUID |
Query parameters — pass via query (string values)
| Name | Type | Description |
|---|---|---|
q | string | 이름/slug/설명/카테고리명 검색 (pg_trgm 유사도) |
category_id | string | 카테고리 UUID 필터 |
status | string | 상태 필터 (평탄 단일) |
status_in | string | 상태 필터 (CSV multi, OR 매칭. 예: archived,draft) |
review_status | string | 심사 상태 필터 (평탄 단일) |
review_status_in | string | 심사 상태 필터 (CSV multi, OR 매칭. 예: not_submitted,pending,rejected) |
operating_status | string | 운영 상태 rollup 필터 (평탄 단일) |
operating_status_in | string | 운영 상태 rollup 필터 (CSV multi, OR 매칭. 예: live,dev) |
sort | string | 정렬 |
page | integer | 페이지 (1-base, 기본 1) |
per_page | integer | 페이지 크기 (기본 50, 최대 200) |
Response — 200 · 앱 목록 (total = 필터 후 전체 건수)
| Name | Type | Description |
|---|---|---|
items | array<object> | |
nextCursor (wire: next_cursor) | string | |
total | integer |
Error statuses: 400 401 403 500 — Error handling
POST /api/v1/tenants/{tenantID}/apps
appsPostApiV1TenantsByTenantIDApps
멤버십이 있는 사용자가 자기가 속한 테넌트 안에 새 앱을 만든다.
- 호출 권한: 본인이 멤버십을 가진 테넌트만 (테넌트 비멤버 → 403).
- slug 는
[a-z0-9-]+패턴, 같은 테넌트 안 unique. 충돌 시 409. - subdomain 미설정 OK — deploy 시 412 까지 지연. 형식 위반 시 400.
- resource_preset 미설정 시 XS. 정의되지 않은 프리셋이면 400.
- deploy_method 미설정 시 docker. 한 번 정한 값은 PATCH 로 변경 불가.
- 부수 효과: Postgres tenant_app schema 가 함께 발급되고 도메인 이벤트 (
AppCreated) 가 발행됨.
| Language | Call |
|---|---|
| node | sdk.apps.create/list(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsPostApiV1TenantsByTenantIDApps(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsPostApiV1TenantsByTenantIDApps(pathParams, query, body) — async: appsPostApiV1TenantsByTenantIDAppsAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsPostApiV1TenantsByTenantIDApps(pathParams, query, body) — suspend |
| python | client.apps.apps_post_api_v1_tenants_by_tenant_id_apps(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_post_api_v1_tenants_by_tenant_id_apps(path_params: …, query: …, body: …) |
| generic | request("appsPostApiV1TenantsByTenantIDApps", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
tenantID required | string | 테넌트 UUID |
Request body — pass via body, wire keys (snake_case) as-is
| Name | Type | Description |
|---|---|---|
auth_mode | string | AuthMode 는 dataapi 의 대표 인증 방식 (선택). 미설정 시 'bearer'. 허용: cookie / bearer / api_key / anonymous. |
category_id | string | CategoryID 는 선택. 비어있으면 카테고리 없음. 카테고리는 같은 테넌트 소속이어야 함. |
data_scopes | array<string> | DataScopes 는 앱이 노출하는 dataapi scope 라벨 목록 (선택). 자유 형식. 빈 entry / 중복은 도메인이 정리. |
deploy_method | string | DeployMethod 는 배포 방식 (선택). 미설정 시 'docker'. 한 번 정한 값은 PATCH 로 변경 불가. 허용: docker / compose / static. |
description | string | Description 은 앱 설명 (선택, 최대 20000자). |
icon_dark_url | string | IconDarkURL 은 다크 모드용 아이콘 URL (선택). |
icon_url | string | IconURL 은 아이콘 이미지 URL (선택, 라이트 모드용). 폼이 pre-create upload-url 로 PUT 한 결과의 public_url. |
name | string | Name 은 사람이 읽는 표시 이름. 1~80자. |
resource_preset | string | ResourcePreset 는 Pod 사양 프리셋 (선택). 미설정 시 'XS'. 허용: XS / S / M / L / XL. |
slug | string | Slug 는 URL 식별자. [a-z0-9-]+ 패턴. 같은 테넌트 안 unique. |
subdomain | string | Subdomain 은 접속 주소 (선택, 2~32자 소문자/숫자/하이픈). 미설정 시 deploy 단계에서 412 — 사용자가 PATCH 로 나중에 채워도 됨. |
Response — 201 · 생성된 앱
| Name | Type | Description |
|---|---|---|
accessUrl (wire: access_url) | string | AccessURL 은 앱의 접속 URL (https://{subdomain}.{tenant_slug}.{base_domain}). subdomain 미설정 앱은 null — FE 는 앱 상세로 fallback. list (Search / List / Discover / users/me/apps embed) 와 단건 (Get) 응답에서 batch enrich 로 채워짐. Create 응답은 항상 null (subdomain 유무와 무관하게 생성 직후엔 enrich 안 함). |
authMode (wire: auth_mode) | string | AuthMode 는 앱 dataapi 가 받는 대표 인증 방식. 가능값: cookie / bearer / api_key / anonymous. 기본 bearer. |
callsCount (wire: calls_count) | integer | CallsCount 는 누적 dataapi 호출 수. denormalized counter — v1 에선 갱신 로직 없이 항상 0; 미래 phase 에서 gateway_log projection 이 채움. |
category | any | Category 는 앱 카테고리의 inline 표현. 단건 조회와 list 응답 (Search / List / Discover) 모두에서 batch enrich 로 채워짐. 카테고리가 없거나 missing 이면 필드 자체가 omit. AppsCount 는 enrich 시 0 (이 컨텍스트에서 카테고리 자체의 분포는 의미 없음). |
categoryId (wire: category_id) | string | CategoryID 는 카테고리 UUID. 카테고리가 없으면 omit. |
costCenter (wire: cost_center) | string | CostCenter 는 비용 귀속 라벨 (팀/부서). null = 미할당 (spec 003). |
createdAt (wire: created_at) | string | CreatedAt 은 생성 시각 (UTC). |
dataScopes (wire: data_scopes) | array<string> | DataScopes 는 앱이 노출하는 dataapi scope 라벨 목록. 자유 형식. 빈 배열이면 scope 정의 없음 — handler 가 scope 검사 안 함. |
deletedAt (wire: deleted_at) | string | DeletedAt 은 soft-delete 시각 (UTC). 살아있는 앱이면 omit. |
deployMethod (wire: deploy_method) | string | DeployMethod is the immutable deployment strategy: docker / compose / static. |
description | string | Description 은 앱 설명 (선택, 최대 20000자). |
iconDarkUrl (wire: icon_dark_url) | string | IconDarkURL 은 다크 모드용 아이콘 URL (선택). 없으면 FE 가 IconURL 로 fallback. |
iconUrl (wire: icon_url) | string | IconURL 은 아이콘 이미지 URL (선택, 라이트 모드용). |
id | string | ID 는 앱 UUID. |
lastDeploymentStatus (wire: last_deployment_status) | string | LastDeploymentStatus 는 가장 최근 deployment 의 raw 도메인 상태. 가능값: pending / running (배포 진행 중) / succeeded (라이브) / failed / cancelled. deployment 가 한 번도 없는 앱 (예: 방금 생성된 draft) 은 null. POST /apps (Create) 응답은 항상 null — 생성 직후엔 deployment 가 없음. List/Get/Search/PATCH 응답은 모두 enrich 된 값. 주의: backend enum 의 running 은 "배포 작업 진행 중" 이고 succeeded 가 "앱이 라이브 (운영중)" 다. FE 매핑 시 둘 혼동 X. |
likeCount (wire: like_count) | integer | LikeCount 는 좋아요 누적 수. |
name | string | Name 은 사람이 읽는 표시 이름. |
operatingStatus (wire: operating_status) | string | OperatingStatus 는 운영 상태 rollup. archived (보관됨) / live (운영중) / dev (개발중). status·review_status·visibility 에서 파생된 요약일 뿐 — 위 raw 필드들은 그대로 응답에 남아 이 rollup 이 다른 상태를 가리지 않는다. archived → status archived (최우선) live → review_status approved + visibility invite_only/public/internet dev → 그 외 (심사 전/대기/반려, 또는 승인됐지만 private) |
owner | any | Owner 는 앱 owner 의 inline 요약 (이름·아바타). 단건 조회 (GET /api/v1/apps/{appID}) 와 list 응답 (Search / List / Discover) 모두에서 batch enrich 로 채워짐 — FE 가 row 마다 단건 GET 을 부르는 N+1 을 피하기 위함. owner_id 가 가리키는 사용자가 missing/soft-deleted 면 필드 자체가 omit. |
ownerId (wire: owner_id) | string | OwnerID 는 앱 소유자 (생성자) 의 사용자 UUID. |
productionDeploymentId (wire: production_deployment_id) | string | ProductionDeploymentID 는 지금 prod 가 서빙 중인 deployment UUID. 성공 배포가 한 번도 없으면 null. 버전 번호는 releases API 에서 조회. |
resourcePreset (wire: resource_preset) | string | ResourcePreset 는 Resources 값을 카탈로그와 매칭한 파생 라벨 (XS/S/M/L/XL 또는 커스텀). 저장하지 않고 매번 계산. (spec 014) |
resources | any | Resources 는 Pod CPU/메모리 사양 (저장된 값 4개). (spec 014) |
resumedAt (wire: resumed_at) | string | ResumedAt 은 마지막 resume 시각 (UTC, spec 312). 한 번도 suspend 한 적 없으면 omit. 현재 suspended_at != nil 이어도 옛 resume 이력이 있으면 값이 남아있을 수 있음 (이력 용도). |
reviewStatus (wire: review_status) | string | ReviewStatus 는 심사 상태. not_submitted / pending / approved / rejected. |
schemaName (wire: schema_name) | string | SchemaName 은 앱 전용 Postgres schema 이름. 생성 시 자동 발급. |
sharedTablesCount (wire: shared_tables_count) | integer | SharedTablesCount 는 이 앱이 다른 앱에 grant 한 dynamic_table 수. denormalized counter — v1 에선 항상 0; 미래 phase 에서 table_grant projection 이 채움. |
slug | string | Slug 는 URL 식별자. [a-z0-9-]+. 같은 테넌트 안 unique. |
stagingDeploymentId (wire: staging_deployment_id) | string | StagingDeploymentID 는 지금 staging 이 서빙 중인 deployment UUID. 옵트인 안 했거나 staging 배포 전이면 null. |
stagingEnabled (wire: staging_enabled) | boolean | StagingEnabled 는 스테이징 옵트인 여부 (spec 016). true 면 push 가 staging 에만 반영되고 prod 는 promote(심사 승인)로만 바뀜. staging URL 은 access_url 의 subdomain 에 --staging 을 붙인 호스트. |
status | string | Status 는 앱 배포 상태 (spec 324). draft (배포 전) / deployed (배포됨) / archived (보관됨). 배포 성공 시 draft→deployed 자동 전이. soft-delete 여부는 별 deleted_at, 최근 배포 attempt 의 raw 상태는 별 last_deployment_status. |
subdomain | string | Subdomain 은 접속 주소 (선택, 2~32자 소문자/숫자/하이픈). 미설정 상태면 omit — 다음 deploy 시 412 까지 deploy 못 함. |
subscriberCount (wire: subscriber_count) | integer | SubscriberCount 는 앱을 "받은" (UserAppAccess grant) 사용자 수. |
summary | string | Summary 는 앱의 "한 줄 소개" (선택, 최대 60자). description(상세 설명) 과 분리된 짧은 소개. 미설정이면 omit. |
suspendedAt (wire: suspended_at) | string | SuspendedAt 은 runtime suspend 시각 (UTC, spec 312). non-nil 이면 K8s namespace 가 정리된 상태 (pod 0). status 와 직교 — 어느 lifecycle 단계든 suspend 가능. live 상태면 omit. |
tenantId (wire: tenant_id) | string | TenantID 는 앱이 속한 테넌트 UUID. |
updatedAt (wire: updated_at) | string | UpdatedAt 은 마지막 수정 시각 (UTC). |
visibility | string | Visibility 는 카탈로그 노출 범위. private / invite_only / public / internet(익명 포함 인터넷 전체). |
Error statuses: 400 401 402 403 404 409 500 — Error handling
GET /api/v1/tenants/{tenantID}/apps/check-availability
appsGetApiV1TenantsByTenantIDAppsCheckAvailability
같은 테넌트 멤버가 앱 생성 폼의 slug / subdomain 입력에 대한 즉시 피드백을 받는 endpoint.
- 호출 권한: 같은 tenant 의 active 멤버 (RequireAuth + RequireTenantMemberOnPath). 비멤버는 403.
- 입력:
?slug=foo/?subdomain=foo/ 둘 다. 두 query 모두 absent 면 400 (required). 빈 값 (?slug=) 은 absent 와 구별 — present-but-empty 는invalid로 응답에 포함. - 부수 효과 없음. 단순 read-only 체크 — 결과는 사용자가 Submit 누르기 전까지 변할 수 있음 (TOCTOU 는 INSERT 의 unique 제약이 최종 가드).
- Rate limit: 120 req/min per IP (debounced 입력 호출 패턴 대비).
| Language | Call |
|---|---|
| node | sdk.apps.checkAvailability(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1TenantsByTenantIDAppsCheckAvailability(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1TenantsByTenantIDAppsCheckAvailability(pathParams, query, body) — async: appsGetApiV1TenantsByTenantIDAppsCheckAvailabilityAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1TenantsByTenantIDAppsCheckAvailability(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_tenants_by_tenant_id_apps_check_availability(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_tenants_by_tenant_id_apps_check_availability(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1TenantsByTenantIDAppsCheckAvailability", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
tenantID required | string | 테넌트 UUID |
Query parameters — pass via query (string values)
| Name | Type | Description |
|---|---|---|
slug | string | 검사할 slug (생략 가능) |
subdomain | string | 검사할 subdomain (생략 가능) |
Response — 200 · 가용성 결과 (각 필드는 보낸 입력만 채워짐)
| Name | Type | Description |
|---|---|---|
slug | any | Slug 는 query 에 slug= 가 있었을 때만 채워짐. 없으면 omit. |
subdomain | any | Subdomain 은 query 에 subdomain= 이 있었을 때만 채워짐. 없으면 omit. |
Error statuses: 400 401 403 429 500 — Error handling
GET /api/v1/tenants/{tenantID}/discover/apps
appsGetApiV1TenantsByTenantIDDiscoverApps
특정 tenant 의 승인·배포된 앱을 caller 권한에 맞춰 반환한다.
- 호출 권한: 해당 tenant 의 active 멤버 (RequireTenantMemberOnPath). platform_admin 자동 통과.
- 노출 조건은 글로벌 디스커버와 동일 — public 또는 internet + 심사 승인(approved) + 배포됨(deployed) 인 앱만 반환. invite_only/private 앱은 디스커버에 나오지 않음.
- static 앱은 active_release_id 가 있어야 노출된다. sort / created_within_days / page / per_page 는 글로벌 둘러보기와 동일.
- tenant_id 가 UUID 형식이 아니면 400.
- 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | sdk.apps.discover.discoverTenant(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| go | client.Apps.AppsGetApiV1TenantsByTenantIDDiscoverApps(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1TenantsByTenantIDDiscoverApps(pathParams, query, body) — async: appsGetApiV1TenantsByTenantIDDiscoverAppsAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1TenantsByTenantIDDiscoverApps(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_tenants_by_tenant_id_discover_apps(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_tenants_by_tenant_id_discover_apps(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1TenantsByTenantIDDiscoverApps", pathParams, query, body) |
Path parameters — pass via pathParams
| Name | Type | Description |
|---|---|---|
tenantID required | string | 테넌트 UUID |
Query parameters — pass via query (string values)
| Name | Type | Description |
|---|---|---|
q | string | 검색 키워드 (이름 / slug / 설명 / 카테고리명 부분 매칭) |
category | string | 카테고리 slug 필터 |
sort | string | 정렬 키 |
created_within_days | integer | 최근 N일 내 생성된 앱만 (양수일 때만 적용) |
page | integer | 페이지 번호 (1-based, 기본 1) |
per_page | integer | 페이지 크기 (기본 50, 최대 200; alias limit) |
Response — 200 · 테넌트 앱스토어 목록
| Name | Type | Description |
|---|---|---|
items | array<object> | |
nextCursor (wire: next_cursor) | string | |
total | integer |
Error statuses: 400 401 403 500 — Error handling
GET /api/v1/users/me/apps
appsGetApiV1UsersMeApps
현재 사용자가 쓸 수 있는 앱 목록을 반환한다 — 본인이 만든 앱(owner self-access)과 받은(grant / invite) 앱을 한 데. 홈 "내 업무공간" 의 소스.
- 호출 권한: 인증된 사용자 (본인 목록만).
- 각 row 의
app필드에 대상 앱의 inline 요약(name / icon / access_url 등)을 embed — FE 가 row 마다 단건 GET 없이 카드를 그리게. - 소유 앱 row 는
app_role=owner, 받은 앱 row 는 멤버 역할. "내가 만든 앱" 섹션은app.owner_id == 나(또는 app_role=owner) 로 분리. - 부수 효과 없음 (read-only).
| Language | Call |
|---|---|
| node | not provided |
| go | client.Apps.AppsGetApiV1UsersMeApps(ctx, axhub.OperationParams{PathParams: …, Query: …, Body: …}) |
| java | client.appsRoutes().appsGetApiV1UsersMeApps(pathParams, query, body) — async: appsGetApiV1UsersMeAppsAsync(…) → CompletableFuture |
| kotlin | client.appsRoutes.appsGetApiV1UsersMeApps(pathParams, query, body) — suspend |
| python | client.apps.apps_get_api_v1_users_me_apps(path_params=…, query=…, body=…) — AsyncAxHubClient awaits the same name |
| ruby | client.apps.apps_get_api_v1_users_me_apps(path_params: …, query: …, body: …) |
| generic | request("appsGetApiV1UsersMeApps", pathParams, query, body) |
Response — 200 · 내 앱 목록 (각 row 에 app summary embed)
| Name | Type | Description |
|---|---|---|
items | array<object> | |
nextCursor (wire: next_cursor) | string | |
total | integer |
Error statuses: 401 500 — Error handling