REST API
ObjectOS가 노출하는 HTTP 표면 — 메타데이터에서 생성되고, 권한으로 범위가 지정되며, OpenAPI로 기술됩니다.
REST API
선언하는 모든 객체는 자동으로 완전한 REST 엔드포인트 세트를 갖게 됩니다.
모든 액션은 POST가 되고, 모든 플로우는
/flows/...로의 POST가 됩니다. 별도로 작성하거나 배포할 API 계층이 없습니다.
기본 URL: https://<your-host>/api/v1.
OpenAPI 사양은 /api/v1/openapi.json에서 실시간으로 제공됩니다.
Authentication
ObjectOS는 Better Auth를 사용합니다. /api/v1
아래의 모든 라우트는 명시적으로 public으로 표시되지 않는 한 인증된 세션이
필요합니다(Public forms 참고). 인증 방식은
apps/<app>/auth.config.ts에서 구성되며, 일반적으로 세션 쿠키 또는
/api/v1/auth/sign-in에서 받은 bearer 토큰입니다.
권한은 라우트별, 레코드별로 확인됩니다. 아래에서 권한 키(예: ai:chat)가
표시된 라우트는 requirePermission(...)을 호출하며, 레코드 수준 접근은 데이터
엔진 내부의 RBAC + 행 수준 보안 + 필드 수준 보안에 의해 적용됩니다.
Discovery
| Path | Method | Purpose |
|---|---|---|
/api/v1 | GET | 서비스 디스커버리 — 등록된 모든 라우트, 버전, 범위 지정 모드를 나열 |
/api/v1/discovery | GET | 위 디스커버리 문서에 대한 명시적 별칭 |
/api/v1/openapi.json | GET | 실행 중인 런타임의 모든 엔드포인트에 대한 OpenAPI 3.0 사양 |
/api/v1/search | GET | 모든 객체의 검색 가능 필드에 대한 전문(full-text) 검색 |
Restricting the API surface
자동 생성된 엔드포인트는 객체 단위로 제어되므로, 라우트 코드를 작성하지 않고도 객체를 API에서 제외하거나 읽기 전용으로 만들 수 있습니다:
apiEnabled(boolean, 기본값true) —false로 설정하면 객체가 REST 표면에서 완전히 제외됩니다. 해당 라우트로의 요청은 404를 반환합니다.apiMethods(선택적 화이트리스트) — 설정하면 나열된 작업만 도달 가능하며, 그 외 작업은 REST 계층에서 거부됩니다. 허용 값:get,list,create,update,delete,upsert,bulk,aggregate,history,search,restore,purge,import,export.
// API로는 절대 쓸 수 없는 읽기 전용 참조 객체:
defineObject({
name: 'exchange_rate',
apiMethods: ['get', 'list'],
// ...fields
})
// API가 절대 노출하지 않는 내부 객체:
defineObject({
name: 'sync_cursor',
apiEnabled: false,
// ...fields
})이 둘은 이제 REST 계층에서 강제됩니다(ADR-0049) — 이전 버전은 이 속성들을 파싱했지만 적용하지는 않았습니다.
Data — /api/v1/data/*
선언하는 모든 객체에 대한 CRUD + 고급 쿼리. :object는 객체의
name입니다(snake_case).
| Path | Method | Purpose |
|---|---|---|
/data/:object | GET | 목록 / 쿼리 — where, orderBy, limit, offset, cursor, expand, select를 쿼리 파라미터로 전달 |
/data/:object/query | POST | 고급 쿼리 — groupBy + aggregations를 포함한 완전한 ObjectQL 본문(ObjectQL 참고) |
/data/:object/:id | GET | 레코드 하나 조회. ?select= 및 ?expand= 지원 |
/data/:object | POST | 생성. 새 레코드와 함께 201 반환 |
/data/:object/:id | PATCH | 업데이트. 낙관적 동시성 제어를 위해 If-Match: <version> 헤더(또는 본문의 expectedVersion)를 전달 — 충돌 시 409 CONCURRENT_UPDATE |
/data/:object/:id | DELETE | 삭제. 동일한 If-Match 규칙 적용 |
/data/:object/import | POST | 대량 가져오기(CSV 또는 JSON). 본문: { format, csv? | rows?, mapping?, dryRun? }. 요청당 최대 5,000행 |
/data/:object/export | POST | 레코드를 csv / xlsx / pdf / json으로 내보내기 |
/data/:object/:id/shares | GET / POST | 레코드별 공유 — 권한 부여 목록 조회, 접근 권한 부여 |
/data/:object/:id/shares/:shareId | DELETE | 공유 취소 |
/data/lead/:id/convert | POST | Salesforce 스타일의 리드 전환(CRM 템플릿). 본문: { accountId?, contactId?, createOpportunity? } |
Quick example
GET /api/v1/data/support_ticket?where={"status":{"$eq":"open"}}&orderBy=-created_at&limit=20
Authorization: Bearer <token>{
"items": [ { "id": "...", "subject": "...", "status": "open" } ],
"total": 137,
"nextCursor": "eyJpZCI6IjAxSDA..."
}AI — /api/v1/ai/*
AI Builder와 agents가 사용하는 엔드포인트입니다.
| Path | Method | Permission | Purpose |
|---|---|---|---|
/ai/models | GET | ai:chat | 구성된 제공자에서 사용 가능한 모델 나열 |
/ai/chat | POST | ai:chat | 단발성 채팅 완성(동기) |
/ai/chat/stream | POST | ai:chat | 스트리밍 채팅(SSE) |
/ai/complete | POST | ai:chat | 원시(raw) 완성 엔드포인트 |
/ai/conversations | GET / POST | ai:chat | 영속 대화 목록 조회 / 생성 |
/ai/conversations/:id | GET / DELETE | ai:chat | 대화 읽기 / 삭제 |
/ai/conversations/:id/messages | POST | ai:chat | 사용자 메시지를 추가하고 에이전트 실행 |
/ai/pending-actions | GET | ai:read | HITL 승인 큐 — AI가 제안한 변경 사항 |
/ai/pending-actions/:id | GET | ai:read | 큐에 대기 중인 변경 사항 검사 |
/ai/pending-actions/:id/approve | POST | ai:approve | 변경 사항 적용 |
/ai/pending-actions/:id/reject | POST | ai:approve | 변경 사항 폐기 |
ai:read와 ai:approve의 분리는 AI Builder를 최종 사용자에게 안전하게
만드는 보안 기본 요소입니다.
Actions — /api/v1/actions/*
선언하는 모든 *.action.ts는 엔드포인트가 됩니다.
| Path | Method | Purpose |
|---|---|---|
/actions/:action | POST | 액션 호출. 본문은 액션의 입력 스키마. 권한과 입력 검증은 액션 선언에서 가져옴 |
각 액션은 AI에게도 action_<name> 도구로 노출됩니다 —
Actions 참고.
Flows — /api/v1/flows/*
| Path | Method | Purpose |
|---|---|---|
/flows/:flow/start | POST | 플로우 시작. 본문은 플로우 입력 |
/flows/:flow/runs/:runId | GET | 실행 중 / 완료된 플로우의 상태 + 단계 출력 |
/flows/:flow/runs/:runId/cancel | POST | 진행 중인 실행 취소 |
Metadata — /api/v1/meta/*
실행 중인 런타임의 메타데이터에 대한 읽기 전용 인트로스펙션. 도구와 Console에 유용합니다.
| Path | Method | Purpose |
|---|---|---|
/meta | GET | 모든 메타데이터 유형(object, view, action, flow, agent, …) |
/meta/:type | GET | 한 유형의 항목 나열. ?package=<id>로 필터링 |
/meta/:type/:name | GET | 항목 하나 조회. ?layers=true는 3-state 디프 뷰(base / package / overlay) 반환 |
/meta/:type/:name/references | GET | 이 항목을 참조하는 모든 메타데이터 항목 찾기 |
/meta/:type/:name/history | GET | 해당 항목의 감사 추적 |
/meta/:type/:section/:name | GET / POST | 섹션화된 메타데이터 항목 읽기 / upsert |
/meta/:type/:section/:name | DELETE | 섹션화된 항목 삭제 |
Sharing & approvals
| Path | Method | Purpose |
|---|---|---|
/sharing/rules | GET / POST / DELETE | 공유 규칙 관리 |
/sharing/rules/:idOrName/evaluate | POST | 컨텍스트에 대해 규칙을 모의 실행(dry-run) |
/approvals/processes | GET / POST | 승인 프로세스 정의 |
/approvals/requests | GET / POST | 승인 요청 제출 / 나열 |
/approvals/requests/:id/approve | POST | 결정: 승인 |
/approvals/requests/:id/reject | POST | 결정: 거부 |
Reports & search
| Path | Method | Purpose |
|---|---|---|
/reports | GET / POST / PATCH | 리포트 CRUD |
/reports/:id/run | POST | 리포트 실행 — 집계된 행 반환 |
/reports/:id/schedule | POST | 반복 전달 예약 |
Public forms
인증되지 않은 유일한 라우트로, FormView.sharing.allowAnonymous를 통해
옵트인합니다.
| Path | Method | Auth |
|---|---|---|
/forms/:slug | GET | public — 폼 스키마 반환 |
/forms/:slug/submit | POST | public — 응답 제출 |
Utilities
| Path | Method | Permission | Purpose |
|---|---|---|---|
/email/send | POST | email:send | 구성된 제공자를 통해 이메일 발송 |
Error envelope
2xx가 아닌 모든 응답은 동일한 형태를 따릅니다:
{
"error": {
"code": "PERMISSION_DENIED",
"message": "Missing ai:approve on conversation 01H…",
"details": { "permission": "ai:approve", "subject": "01H…" }
}
}일반적인 코드: UNAUTHENTICATED, PERMISSION_DENIED,
VALIDATION_ERROR, NOT_FOUND, CONCURRENT_UPDATE,
RATE_LIMITED, INTERNAL.
Versioning
/api/v1은 안정(stable) API입니다. 호환성을 깨는 변경 사항은 /api/v2로
가며, 두 버전은 하나의 마이너 릴리스 동안 병렬로 제공됩니다. 현재 버전과
지원 중단(deprecation) 기한은 GET /api/v1에 있습니다.
See also
- ObjectQL —
/data/*가 사용하는 쿼리 언어 - Field types — 데이터가 가질 수 있는 형태
- Build → Actions — 커스텀 엔드포인트 선언
- Security — 모든 라우트가 실행 전에 확인하는 것