워드프레스 REST API 카테고리 ID를 이름으로 매핑하는 실전 코드: AI 에이전트 자동 발행에서 막힌 지점

워드프레스 REST API로 글을 자동 발행할 때 카테고리는 이름이 아니라 ID 배열로 보내야 합니다. 그래서 핵심은 먼저 /wp-json/wp/v2/categories에서 카테고리 목록을 가져와 이름 → ID 딕셔너리를 만든 뒤, 글 발행 요청의 categories에 해당 ID를 넣는 것입니다.

이 글에는 제휴(어필리에이트) 링크가 포함될 수 있으며, 링크를 통해 가입·구매 시 소정의 수수료를 받을 수 있습니다. 추천은 실제 사용 경험에 기반합니다.

카테고리 API 응답을 먼저 확인한 뒤, 초안 발행 스크립트에 이름→ID 매핑 단계를 추가해보세요.

저는 Claude Code와 n8n으로 블로그 초안 생성·검수·발행 흐름을 만들다가 이 부분에서 한 번 막혔습니다. AI는 “AI 코딩/에이전트”처럼 사람이 읽는 카테고리명을 잘 뽑아주지만, WordPress REST API는 [12] 같은 숫자를 요구하니까요.

바로 적용할 순서
아래 코드에서 사이트 주소와 인증값만 바꾼 뒤, 먼저 카테고리 매핑 JSON이 제대로 찍히는지 확인해보세요.

가장 단순한 구조: 카테고리 목록을 한 번 읽고 매핑한다

워드프레스 카테고리 API는 기본적으로 이름, 슬러그, ID를 돌려줍니다. 자동 발행 도구에서는 카테고리명이 들어오면 그 이름을 ID로 바꿔서 글 생성 API에 넘기면 됩니다.

Node.js fetch 예시

Cursor, Claude Code, Codex 같은 AI 코딩 에이전트에게 붙여 넣고 수정하기 좋은 형태입니다. 실제 운영에서는 환경변수로 사이트 URL과 인증 정보를 분리하세요.

const WP_BASE_URL = 'https://example.com';
const WP_USER = process.env.WP_USER;
const WP_APP_PASSWORD = process.env.WP_APP_PASSWORD;

function authHeader() {
  const token = Buffer.from(`${WP_USER}:${WP_APP_PASSWORD}`).toString('base64');
  return { Authorization: `Basic ${token}` };
}

async function getCategoryMap() {
  const res = await fetch(`${WP_BASE_URL}/wp-json/wp/v2/categories?per_page=100`, {
    headers: authHeader()
  });

  if (!res.ok) throw new Error(`Category fetch failed: ${res.status}`);

  const categories = await res.json();
  return categories.reduce((map, cat) => {
    map[cat.name.trim()] = cat.id;
    return map;
  }, {});
}

async function createPostWithCategory(title, html, categoryName) {
  const categoryMap = await getCategoryMap();
  const categoryId = categoryMap[categoryName];

  if (!categoryId) {
    throw new Error(`Unknown category: ${categoryName}`);
  }

  const res = await fetch(`${WP_BASE_URL}/wp-json/wp/v2/posts`, {
    method: 'POST',
    headers: {
      ...authHeader(),
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      title,
      content: html,
      status: 'draft',
      categories: [categoryId]
    })
  });

  return await res.json();
}

처음부터 publish로 보내지 말고 draft로 테스트하는 편이 안전합니다. 특히 AI가 카테고리명을 살짝 다르게 쓰면 의도하지 않은 분류로 들어가거나 요청이 실패할 수 있습니다.

Python requests로 쓰는 경우

Zapier Webhooks나 Make보다 직접 제어가 필요하면 Python 스크립트가 편합니다. 크론으로 돌리거나 GitHub Actions와 붙이기도 쉽습니다.

import os
import requests

WP_BASE_URL = 'https://example.com'
AUTH = (os.getenv('WP_USER'), os.getenv('WP_APP_PASSWORD'))

def get_category_map():
    url = f'{WP_BASE_URL}/wp-json/wp/v2/categories?per_page=100'
    r = requests.get(url, auth=AUTH, timeout=20)
    r.raise_for_status()
    return {c['name'].strip(): c['id'] for c in r.json()}

def category_id_by_name(name):
    category_map = get_category_map()
    if name not in category_map:
        raise ValueError(f'Category not found: {name}')
    return category_map[name]

cat_id = category_id_by_name('빌더 일지/프로젝트')
print(cat_id)

이름, 슬러그, 하드코딩 중 무엇을 쓸까?

작은 블로그는 하드코딩도 괜찮지만, monstereae처럼 여러 주제 카테고리를 계속 조정한다면 API로 읽어오는 방식이 유지보수에 유리합니다.

방식 장점 주의할 점 추천 상황
이름 → ID 매핑 AI가 만든 분류명을 그대로 쓰기 쉽다 띄어쓰기·특수문자 차이에 민감하다 ChatGPT, Claude Code가 카테고리명을 출력하는 워크플로
슬러그 → ID 매핑 영문 키라 안정적이다 AI 출력값을 슬러그로 맞춰야 한다 n8n, Make에서 규칙 기반 자동화할 때
ID 하드코딩 가장 빠르고 단순하다 카테고리 변경 시 코드 수정 필요 카테고리가 3~5개로 거의 안 바뀌는 사이트

실전 예: AI 초안의 category를 발행 가능한 값으로 바꾸기

가상의 자동화 흐름을 보겠습니다. Perplexity로 자료를 확인하고, Claude Code가 글 JSON을 만들고, n8n이 워드프레스에 초안을 넣는 구조입니다. AI 출력은 보통 이렇게 나옵니다.

{
  title: 'Cursor로 PR 리뷰 자동화하기',
  category: 'AI 코딩/에이전트',
  body_html: '<p>...</p>'
}

이때 n8n의 Function 노드나 자체 서버에서 category 값을 categories: [카테고리ID]로 변환하면 됩니다. 카테고리명이 없으면 기본 카테고리로 보내기보다 실패 처리하는 편을 권합니다. 잘못 분류된 글은 나중에 SEO 구조를 정리할 때 더 큰 비용이 됩니다.

추천 대상: 이런 자동 발행 셋업이라면 꼭 넣으세요

이 매핑 코드는 특히 AI 콘텐츠 파이프라인을 직접 만드는 사람에게 필요합니다. Claude Code, Codex, Cursor로 워드프레스 발행 스크립트를 만들거나, Airtable에 쌓인 초안을 n8n으로 발행하거나, Slack 승인 후 자동으로 초안 생성하는 흐름이라면 카테고리 ID 변환 단계가 거의 필수입니다.

반대로 관리자 화면에서 손으로 글을 쓰는 비중이 높다면 굳이 복잡하게 만들 필요는 없습니다. 몇 개의 고정 카테고리 ID를 메모해두고 요청 본문에 직접 넣는 것으로 충분합니다.

자주 막히는 지점

1. 카테고리가 100개를 넘으면 일부만 가져옵니다

per_page=100이 한 번에 가져올 수 있는 일반적인 최대치입니다. 카테고리가 더 많다면 응답 헤더의 X-WP-TotalPages를 보고 페이지를 순회해야 합니다.

2. 이름이 같은 카테고리가 있으면 충돌합니다

부모 카테고리가 다른데 이름이 같은 경우가 있습니다. 이때는 이름보다 슬러그 기준 매핑이 안전합니다. 예를 들어 ai-coding-agent 같은 고정 슬러그를 AI 출력 규칙에 넣어두면 오류가 줄어듭니다.

3. 인증은 애플리케이션 비밀번호가 가장 편합니다

워드프레스 사용자 프로필에서 Application Password를 발급해 Basic Auth로 쓰는 방식이 간단합니다. 단, 공개 저장소에 올리면 안 되며, GitHub Actions나 서버 환경변수에 넣어 관리하세요.

FAQ

Q. 카테고리 이름 대신 슬러그로 매핑해도 되나요?

네. 오히려 자동화에서는 슬러그가 더 안정적입니다. 다만 AI가 사람이 읽는 카테고리명을 출력하는 흐름이라면 이름 매핑이 구현이 빠릅니다.

Q. 새 카테고리가 없으면 자동 생성하는 게 좋을까요?

운영 블로그라면 권하지 않습니다. AI가 오타를 내면 불필요한 카테고리가 계속 생깁니다. 없는 카테고리는 에러로 멈추고 사람이 확인하는 편이 안전합니다.

Q. 글 생성 API에는 카테고리 ID를 하나만 넣을 수 있나요?

아닙니다. categories: [3, 12]처럼 여러 개를 배열로 보낼 수 있습니다. 단, 주 카테고리 개념은 테마나 SEO 플러그인 설정과 별도로 확인해야 합니다.

다음 행동

오늘 바로 할 일은 간단합니다. 먼저 브라우저에서 https://내도메인/wp-json/wp/v2/categories?per_page=100을 열어 카테고리 응답이 보이는지 확인하세요. 그다음 위 코드로 이름 또는 슬러그 매핑을 만들고, 글 발행은 반드시 초안 상태로 한 번 테스트해보면 됩니다.

AI 에이전트가 글을 잘 써도 마지막 발행 단계에서 분류가 틀어지면 운영 품질이 떨어집니다. 작은 매핑 코드 하나가 자동화 전체의 신뢰도를 꽤 많이 올려줍니다.

관련 링크

글쓴이 용기

AI 코딩 에이전트로 직접 빌드하는 개발자. Claude Code·Codex 실사용 후기와 빌더 일지를 씁니다.

지식창고