API v1

API 문서

Statix API로 페이지 목록 조회, 생성, 삭제를 자동화할 수 있습니다. AI 에이전트, CI 파이프라인, 배포 스크립트에서 바로 호출하세요.

베이스 URL

https://flzwoyvuujcgfnmurjdj.supabase.co/functions/v1/api

모든 요청과 응답은 UTF-8 JSON입니다. 성공 응답은 data 키에, 실패 응답은 error 키에 담깁니다.

인증

모든 엔드포인트는 API Key가 필요합니다. 대시보드 > API Key에서 발급한 키를 Authorization 헤더에 담아 보내세요.

Authorization: Bearer stx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

헤더 이름을 바꾸기 어려운 환경이라면 x-api-key: stx_... 도 지원합니다.

키는 서버에서만 사용하세요.

API Key는 계정 전체 권한을 갖습니다. 브라우저 코드나 공개 저장소에 넣지 마세요. 유출이 의심되면 대시보드에서 즉시 만료 처리하고 새로 발급하면 됩니다.

스코프

키를 발급할 때 권한을 고릅니다. 필요한 최소 권한만 주는 편이 안전합니다.

pages:read
내 페이지 목록을 조회합니다.
GET /pages
pages:write
페이지를 생성하고 삭제합니다.
POST /pages, DELETE /pages/{id}

엔드포인트

GET/pages
pages:read
내 페이지 목록을 최신 생성 순으로 반환합니다.

쿼리 파라미터

이름타입필수설명
limitnumber선택한 번에 가져올 개수. 기본 20, 최대 100.
offsetnumber선택건너뛸 개수. 기본 0.
publishedtrue | false선택게시 상태로 필터링합니다. 생략하면 전체.

요청

curl "https://flzwoyvuujcgfnmurjdj.supabase.co/functions/v1/api/pages?limit=20" \
  -H "Authorization: Bearer $STATIX_API_KEY"

응답 200

{
  "data": [
    {
      "id": "8f14e45f-ceea-467a-9f8b-3f2c1d4e5a6b",
      "title": "개인정보처리방침",
      "slug": "privacy-policy",
      "published": true,
      "view_count": 128,
      "url": "https://mysubdomain.statix.kr/privacy-policy",
      "created_at": "2026-08-01T02:11:43.201Z",
      "updated_at": "2026-08-12T09:30:02.118Z"
    }
  ],
  "pagination": {
    "limit": 20,
    "offset": 0,
    "total": 1,
    "has_more": false
  }
}
POST/pages
pages:write
새 페이지를 만들고 첫 버전을 저장합니다.

요청 바디

이름타입필수설명
titlestring필수페이지 제목.
contentstring필수페이지 HTML. 최대 1MB.
slugstring선택URL 경로. 소문자 영문·숫자·하이픈(-)·점(.)만 사용합니다. 생략하면 제목에서 자동 생성됩니다.
publishedboolean선택게시 여부. 기본 false(비공개).

요청

curl -X POST "https://flzwoyvuujcgfnmurjdj.supabase.co/functions/v1/api/pages" \
  -H "Authorization: Bearer $STATIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "이용약관",
    "slug": "terms",
    "content": "<h1>이용약관</h1><p>...</p>",
    "published": true
  }'

응답 201

{
  "data": {
    "id": "3b2a1c9d-7e6f-4a5b-8c9d-0e1f2a3b4c5d",
    "title": "이용약관",
    "slug": "terms",
    "published": true,
    "view_count": 0,
    "url": "https://mysubdomain.statix.kr/terms",
    "current_version_id": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
    "version_number": 1,
    "created_at": "2026-08-23T04:22:10.339Z",
    "updated_at": "2026-08-23T04:22:10.339Z"
  }
}

플랜 한도를 넘으면 429 limit_exceeded가 반환됩니다. Free는 100개, Pro는 10,000개까지 만들 수 있습니다.

DELETE/pages/{id}
pages:write
페이지와 모든 버전 기록을 삭제합니다. 되돌릴 수 없습니다.

경로 파라미터

이름타입필수설명
iduuid필수삭제할 페이지 ID. 목록 조회 응답의 id 값입니다.

요청

curl -X DELETE "https://flzwoyvuujcgfnmurjdj.supabase.co/functions/v1/api/pages/3b2a1c9d-7e6f-4a5b-8c9d-0e1f2a3b4c5d" \
  -H "Authorization: Bearer $STATIX_API_KEY"

응답 200

{
  "data": {
    "id": "3b2a1c9d-7e6f-4a5b-8c9d-0e1f2a3b4c5d",
    "deleted": true
  }
}

에러

실패 응답은 항상 아래 형태입니다. code로 분기하세요. HTTP 상태 코드만 보고 판단하지 않아도 됩니다.

{
  "error": {
    "code": "insufficient_scope",
    "message": "이 요청에는 pages:write 스코프가 필요합니다.",
    "requiredScope": "pages:write",
    "grantedScopes": ["pages:read"]
  }
}
codeHTTP의미
unauthorized401Authorization 헤더가 없습니다.
invalid_api_key401키가 존재하지 않거나, 만료 처리됐거나, 만료일이 지났습니다.
insufficient_scope403이 요청에 필요한 스코프가 키에 없습니다.
validation_error400요청 값이 올바르지 않습니다.
not_found404대상을 찾을 수 없습니다.
conflict409이미 사용 중인 slug입니다.
limit_exceeded429플랜별 페이지 생성 한도에 도달했습니다.
method_not_allowed405해당 경로가 지원하지 않는 메서드입니다.
internal_error500서버 오류입니다.

JavaScript 예제

Node.js 18 이상이면 별도 패키지 없이 fetch로 호출할 수 있습니다.

const BASE_URL = "https://flzwoyvuujcgfnmurjdj.supabase.co/functions/v1/api";
const API_KEY = process.env.STATIX_API_KEY;

async function statix(path, init = {}) {
  const response = await fetch(BASE_URL + path, {
    ...init,
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
      ...init.headers,
    },
  });

  const payload = await response.json();

  if (!response.ok) {
    throw new Error(`[${payload.error.code}] ${payload.error.message}`);
  }

  return payload;
}

// 목록 조회
const { data: pages } = await statix("/pages?limit=50");

// 생성
const { data: created } = await statix("/pages", {
  method: "POST",
  body: JSON.stringify({
    title: "새 랜딩 페이지",
    content: "<h1>안녕하세요</h1>",
    published: true,
  }),
});

console.log("생성됨:", created.url);

// 삭제
await statix(`/pages/${created.id}`, { method: "DELETE" });
시작할 준비가 됐나요?
대시보드에서 키를 발급하면 바로 위 예제를 실행할 수 있습니다.