v1

API 문서

X-Blog REST API를 사용하여 블로그 데이터에 프로그래밍 방식으로 접근하고 관리할 수 있습니다. 게시글, 프로젝트, 연구 노트, 프로모션을 외부 애플리케이션에서 제어하세요.

1. 개요

X-Blog API는 RESTful 아키텍처를 따르며, 모든 요청과 응답은 JSON 형식을 사용합니다.

기본 URL

https://your-blog.x-blog.com/api/v1

콘텐츠 타입

Content-Type: application/json
Accept: application/json

버전 관리

API 버전은 URL 경로에 포함됩니다. 현재 최신 버전은 v1입니다. 이전 버전은 최소 12개월 동안 지원됩니다.

2. 인증

모든 API 요청에는 인증이 필요합니다. API 키는 블로그 설정 페이지에서 생성할 수 있습니다.

Bearer 토큰 인증

API 키를 Authorization 헤더에 Bearer 토큰으로 포함시킵니다.

curl -H "Authorization: Bearer your_api_key_here" \
  https://your-blog.x-blog.com/api/v1/posts

보안 주의사항

API 키를 클라이언트 사이드 코드나 공개 저장소에 노출하지 마세요. 서버 사이드에서만 사용하고, 키가 유출된 경우 즉시 블로그 설정에서 재발급하세요.

3. 게시글 API

블로그 게시글을 생성, 조회, 수정, 삭제합니다.

GET /api/v1/posts

모든 게시글 목록을 조회합니다.

요청

curl -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/posts

응답

{
  "data": [
      {
        "slug": "hello-world",
        "title": "Hello World",
        "body": "Welcome to my blog...",
        "status": "published",
        "tags": ["intro", "welcome"],
        "published_at": "2026-02-07T09:00:00Z"
      }
    ]
}
GET /api/v1/posts/:slug

특정 게시글을 slug로 조회합니다.

요청

curl -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/posts/hello-world

응답

{
  "data": {
      "slug": "hello-world",
      "title": "Hello World",
      "body": "Welcome to my blog...",
      "status": "published",
      "tags": ["intro", "welcome"],
      "published_at": "2026-02-07T09:00:00Z"
    }
}
POST /api/v1/posts

새 게시글을 생성합니다.

요청

curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"post":{"title":"New Post","body":"Post content...","tags":["elixir"]}}' \
  https://your-blog.x-blog.com/api/v1/posts

응답

{
  "data": {
      "slug": "new-post",
      "title": "New Post",
      "body": "Post content...",
      "status": "draft",
      "tags": ["elixir"],
      "published_at": null
    }
}
PUT /api/v1/posts/:slug

기존 게시글을 수정합니다.

요청

curl -X PUT \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"post":{"title":"Updated Title","body":"Updated content..."}}' \
  https://your-blog.x-blog.com/api/v1/posts/hello-world

응답

{
  "data": {
      "slug": "hello-world",
      "title": "Updated Title",
      "body": "Updated content...",
      "status": "published",
      "updated_at": "2026-02-07T11:00:00Z"
    }
}
DELETE /api/v1/posts/:slug

게시글을 삭제합니다.

요청

curl -X DELETE \
  -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/posts/hello-world

응답

{
  "data": {
      "message": "Post deleted successfully"
    }
}

4. 프로젝트 API

프로젝트를 생성, 조회, 수정, 삭제하고 게시 상태를 관리합니다.

GET /api/v1/projects

모든 프로젝트 목록을 조회합니다.

요청

curl -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/projects

응답

{
  "data": [
      {
        "slug": "my-saas-app",
        "title": "My SaaS App",
        "description": "A productivity tool...",
        "status": "published",
        "url": "https://my-saas.com"
      }
    ]
}
GET /api/v1/projects/:slug

특정 프로젝트를 slug로 조회합니다.

요청

curl -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/projects/my-saas-app

응답

{
  "data": {
      "slug": "my-saas-app",
      "title": "My SaaS App",
      "description": "A productivity tool...",
      "status": "published",
      "url": "https://my-saas.com"
    }
}
POST /api/v1/projects

새 프로젝트를 생성합니다.

요청

curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"project":{"title":"New Project","description":"Summary","url":"https://example.com"}}' \
  https://your-blog.x-blog.com/api/v1/projects

응답

{
  "data": {
      "slug": "new-project",
      "title": "New Project",
      "status": "draft",
      "url": "https://example.com"
    }
}
PUT /api/v1/projects/:slug

기존 프로젝트를 수정합니다.

요청

curl -X PUT \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"project":{"title":"Updated Project","description":"New summary"}}' \
  https://your-blog.x-blog.com/api/v1/projects/my-saas-app

응답

{
  "data": {
      "slug": "my-saas-app",
      "title": "Updated Project",
      "status": "published"
    }
}
DELETE /api/v1/projects/:slug

프로젝트를 삭제합니다.

요청

curl -X DELETE \
  -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/projects/my-saas-app

응답

{
  "data": {
      "message": "Project deleted successfully"
    }
}
POST /api/v1/projects/:slug/publish

프로젝트를 게시(publish) 상태로 변경합니다.

요청

curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/projects/my-saas-app/publish

응답

{
  "data": {
      "slug": "my-saas-app",
      "status": "published",
      "published_at": "2026-02-07T12:00:00Z"
    }
}
POST /api/v1/projects/:slug/unpublish

프로젝트를 비공개(draft) 상태로 변경합니다.

요청

curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/projects/my-saas-app/unpublish

응답

{
  "data": {
      "slug": "my-saas-app",
      "status": "draft",
      "published_at": null
    }
}

5. 연구 노트 API

연구 노트를 생성, 조회, 수정, 삭제하고 게시 상태를 관리합니다.

GET /api/v1/research

모든 연구 노트 목록을 조회합니다.

요청

curl -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/research

응답

{
  "data": [
      {
        "slug": "elixir-genserver-patterns",
        "title": "Elixir GenServer Patterns",
        "abstract": "A study of common GenServer patterns",
        "status": "published"
      }
    ]
}
GET /api/v1/research/:slug

특정 연구 노트를 slug로 조회합니다.

요청

curl -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/research/elixir-genserver-patterns

응답

{
  "data": {
      "slug": "elixir-genserver-patterns",
      "title": "Elixir GenServer Patterns",
      "abstract": "A study of common GenServer patterns",
      "status": "published"
    }
}
POST /api/v1/research

새 연구 노트를 생성합니다.

요청

curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"research":{"title":"New Research","body":"Findings...","abstract":"Summary"}}' \
  https://your-blog.x-blog.com/api/v1/research

응답

{
  "data": {
      "slug": "new-research",
      "title": "New Research",
      "status": "draft",
      "published_at": null
    }
}
PUT /api/v1/research/:slug

기존 연구 노트를 수정합니다.

요청

curl -X PUT \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"research":{"title":"Updated Research","abstract":"Revised summary"}}' \
  https://your-blog.x-blog.com/api/v1/research/elixir-genserver-patterns

응답

{
  "data": {
      "slug": "elixir-genserver-patterns",
      "title": "Updated Research",
      "status": "published"
    }
}
DELETE /api/v1/research/:slug

연구 노트를 삭제합니다.

요청

curl -X DELETE \
  -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/research/elixir-genserver-patterns

응답

{
  "data": {
      "message": "Research deleted successfully"
    }
}
POST /api/v1/research/:slug/publish

연구 노트를 게시(publish) 상태로 변경합니다.

요청

curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/research/elixir-genserver-patterns/publish

응답

{
  "data": {
      "slug": "elixir-genserver-patterns",
      "status": "published",
      "published_at": "2026-02-07T12:00:00Z"
    }
}
POST /api/v1/research/:slug/unpublish

연구 노트를 비공개(draft) 상태로 변경합니다.

요청

curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/research/elixir-genserver-patterns/unpublish

응답

{
  "data": {
      "slug": "elixir-genserver-patterns",
      "status": "draft",
      "published_at": null
    }
}

6. 프로모션 API

프로모션 배너를 생성, 조회, 수정, 삭제하고 활성화 상태를 관리합니다.

GET /api/v1/promotions/hero

현재 활성화된 히어로 프로모션을 조회합니다.

요청

curl -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/promotions/hero

응답

{
  "data": {
      "id": 1,
      "title": "Spring Sale",
      "description": "Get 50% off all plans!",
      "cta_text": "Upgrade Now",
      "is_active": true,
      "position": "hero"
    }
}
GET /api/v1/promotions

모든 프로모션 목록을 조회합니다.

요청

curl -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/promotions

응답

{
  "data": [
      {
        "id": 1,
        "title": "Spring Sale",
        "is_active": true,
        "position": "hero"
      }
    ]
}
POST /api/v1/promotions

새 프로모션을 생성합니다.

요청

curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"promotion":{"title":"Summer Event","description":"Limited offer","position":"banner"}}' \
  https://your-blog.x-blog.com/api/v1/promotions

응답

{
  "data": {
      "id": 2,
      "title": "Summer Event",
      "is_active": false,
      "position": "banner"
    }
}
PUT /api/v1/promotions/:id

기존 프로모션을 수정합니다.

요청

curl -X PUT \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"promotion":{"title":"Updated Sale","description":"New description"}}' \
  https://your-blog.x-blog.com/api/v1/promotions/1

응답

{
  "data": {
      "id": 1,
      "title": "Updated Sale",
      "is_active": true
    }
}
DELETE /api/v1/promotions/:id

프로모션을 삭제합니다.

요청

curl -X DELETE \
  -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/promotions/1

응답

{
  "data": {
      "message": "Promotion deleted successfully"
    }
}
POST /api/v1/promotions/:id/activate

프로모션을 활성화합니다.

요청

curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/promotions/1/activate

응답

{
  "data": {
      "id": 1,
      "title": "Spring Sale",
      "is_active": true
    }
}
POST /api/v1/promotions/:id/deactivate

프로모션을 비활성화합니다.

요청

curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  https://your-blog.x-blog.com/api/v1/promotions/1/deactivate

응답

{
  "data": {
      "id": 1,
      "title": "Spring Sale",
      "is_active": false
    }
}

7. 에러 처리

API는 표준 HTTP 상태 코드를 사용하며, 에러 발생 시 일관된 JSON 형식으로 응답합니다.

상태 코드 설명
200 성공
201 리소스 생성 완료
400 잘못된 요청 - 요청 본문이 올바르지 않습니다
401 인증 실패 - 유효하지 않은 API 키
403 권한 없음 - 해당 리소스에 대한 접근 권한이 없습니다
404 리소스를 찾을 수 없습니다
422 유효성 검증 실패 - 입력값이 올바르지 않습니다
429 요청 한도 초과 - 잠시 후 다시 시도하세요
500 서버 내부 오류

인증 에러 응답 예시

{
  "error": {
    "status": 401,
    "message": "Invalid or missing API key"
  }
}

유효성 검증 에러 응답 예시

{
  "error": {
    "status": 422,
    "message": "Validation failed",
    "errors": {
      "title": ["can't be blank"],
      "body": ["can't be blank"]
    }
  }
}

리소스 미발견 에러 응답 예시

{
  "error": {
    "status": 404,
    "message": "Resource not found"
  }
}

8. 속도 제한

API 남용을 방지하기 위해 요금제별 속도 제한이 적용됩니다.

요금제 분당 요청 수 일일 요청 수
Business 60 10,000

속도 제한 응답 헤더

모든 API 응답에는 현재 속도 제한 상태를 나타내는 헤더가 포함됩니다.

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1707300000

속도 제한 초과 시 응답

# HTTP 429 Too Many Requests
{
  "error": {
    "status": 429,
    "message": "Rate limit exceeded. Please retry after 60 seconds.",
    "retry_after": 60
  }
}

속도 제한에 도달하면 X-RateLimit-Reset 헤더의 Unix 타임스탬프까지 기다린 후 요청을 재시도하세요. 지수 백오프(exponential backoff)를 구현하는 것을 권장합니다.

API 사용을 시작하세요

Business 요금제에서 API 접근이 가능합니다. 블로그 설정에서 API 키를 생성하여 시작하세요.