apps
create/update apps, access, comments, env vars, static release, staging, raw-db toggle
29 operations — create/update apps, access, comments, env vars, static release, staging, raw-db toggle
GET /api/v1/apps/discover
appsGetApiV1AppsDiscover
모든 tenant 의 공개 승인·배포 앱을 한 데 모아 반환한다.
- 호출 권한: 인증된 사용자. 결과는 caller 의 멤버십/소유권과 무관 — visibility=public 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. 잘못된 값이면 무시. - 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(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| 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 public/invite_only 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. |
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. private 외로 바꾸려면 review_status=approved 필수 (그 전엔 412). - 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. private 외로 바꾸려면 review_status=approved 여야 함 — 그 전엔 412. |
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 public/invite_only 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. |
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일 때만 가능. 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 의 5-enum (owner | platform_admin | tenant_admin | app_member | tenant_member). 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 의 5-enum (owner | platform_admin | tenant_admin | app_member | tenant_member). 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 public/invite_only 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. |
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.envVars(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| 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.envVars(…) — resource model — see the package's TypeScript definitions for arguments and return types |
| 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
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 로 해소. 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 public/invite_only 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. |
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 앱은 active tenant member 에게, invite_only 앱은 소유자/tenant_admin/platform_admin/초대 사용자에게, private 앱은 소유자/tenant_admin/platform_admin 에게만 노출.
- 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