English · 한국어

API 문서

Apiryner API로 그럴듯한 목 데이터를 만드는 데 필요한 모든 것.

빠른 시작

세 단계면 랜덤 데이터가 나옵니다:

  1. 레이아웃 만들기 — 필드 이름과 타입으로 데이터 스키마를 정의합니다
  2. API 키 발급 — API Keys 페이지에서 하나 만듭니다
  3. 요청 보내기 — 레이아웃 슬러그로 API를 호출합니다

요청 예시:

curl -H "X-API-Key: ak_your_key_here" \
  "https://api.apiryner.com/v1/layouts/user-profile?count=2&locale=ko"

응답 예시:

[
  {
    "id": 1,
    "name": "김서연",
    "email": "[email protected]",
    "age": 28,
    "is_active": true
  },
  {
    "id": 2,
    "name": "박준호",
    "email": "[email protected]",
    "age": 45,
    "is_active": true
  }
]

인증

Apiryner는 두 가지 인증 방식을 지원합니다:

API 키 (읽기 전용)

API 키를 X-API-Key 헤더에 담아 보냅니다. API 키로는 데이터를 읽고 생성하는 것만 가능합니다.

curl -H "X-API-Key: ak_your_key_here" \
  https://api.apiryner.com/v1/layouts/my-layout

Bearer 토큰 (전체 권한)

쓰기(생성·수정·삭제)에는 OAuth 2.0 Bearer 토큰을 씁니다. 가장 간단한 방법은 CLI 로그인으로, OAuth PKCE 플로를 돌리고 토큰을 로컬에 저장합니다:

# OAuth PKCE로 로그인 (브라우저가 열립니다)
npx apiryner login

# 토큰 사용
curl -H "Authorization: Bearer oat_your_token" \
  -X POST https://api.apiryner.com/v1/layouts \
  -H "Content-Type: application/json" \
  -d '{"name": "Users", "slug": "users", "schema": {"id": {"type": "uuid"}}}'

토큰은 동의 화면에서 허용한 스코프를 갖습니다. read는 GET 요청을, write는 전부를 허용합니다. 토큰의 스코프를 벗어난 요청은 403 insufficient_scope를, API 키로 보낸 쓰기 요청은 403 forbidden을 돌려줍니다.

엔드포인트

메서드 엔드포인트 인증 설명
데이터 생성
GET /v1/layouts/:slug API Key / Bearer 레이아웃으로 데이터 생성
GET /v1/bundles/:slug API Key / Bearer 번들에 묶인 레이아웃을 한 응답으로 생성
GET /v1/snapshots/:slug API Key / Bearer 스냅샷에 고정된 데이터 서빙
레이아웃
GET /v1/layouts API Key / Bearer 내 레이아웃 목록
POST /v1/layouts Bearer 레이아웃 생성
PUT /v1/layouts/:slug Bearer 레이아웃 수정
DELETE /v1/layouts/:slug Bearer 레이아웃 삭제
POST /v1/layouts/import Bearer JSON 샘플에서 스키마를 추론해 레이아웃으로 저장
번들
GET /v1/bundles API Key / Bearer 내 번들 목록
POST /v1/bundles Bearer 레이아웃 ID로 번들 생성
PUT /v1/bundles/:slug Bearer 번들 수정
DELETE /v1/bundles/:slug Bearer 번들 삭제
스냅샷
GET /v1/snapshots API Key / Bearer 내 스냅샷 목록
POST /v1/snapshots Bearer 데이터를 생성해 스냅샷으로 고정
PUT /v1/snapshots/:slug Bearer 스냅샷의 이름이나 데이터 교체
DELETE /v1/snapshots/:slug Bearer 스냅샷 삭제
타입과 템플릿
GET /v1/types API Key / Bearer 전체 데이터 타입 목록
GET /v1/types/:name API Key / Bearer 타입 하나의 상세
GET /v1/templates API Key / Bearer 프리셋 템플릿 목록
GET /v1/templates/:id API Key / Bearer 템플릿 하나의 레이아웃 정의
POST /v1/templates/:id/apply Bearer 템플릿으로 레이아웃 생성
웹훅
GET /v1/webhooks API Key / Bearer 내 웹훅 목록
POST /v1/webhooks Bearer URL을 이벤트에 구독
DELETE /v1/webhooks/:id Bearer 웹훅 삭제
GET /v1/webhooks/:id/deliveries API Key / Bearer 최근 전송 시도 내역
계정
GET /v1/account/usage API Key / Bearer 이번 기간의 요청·레코드 사용량
GET /v1/account/api-keys API Key / Bearer 내 API 키 목록
POST /v1/account/api-keys Bearer API 키 생성
PUT /v1/account/api-keys/:id/deactivate Bearer API 키 비활성화
DELETE /v1/account/api-keys/:id Bearer API 키 삭제

모든 /v1 경로에는 자격 증명이 필요합니다. 비인증 접근은 없습니다. API 키는 읽기 전용이라 Bearer로 표시된 행은 write 스코프를 가진 OAuth 토큰이 필요합니다. 목록 엔드포인트는 limit(최대 100)과 offset을 받습니다.

데이터 생성 쿼리 파라미터

GET /v1/layouts/:slug를 호출할 때:

파라미터 타입 기본값 설명
count integer 레이아웃에 저장된 값 생성할 레코드 수. 플랜의 요청당 최대치를 넘으면 거절되지 않고 그 값으로 잘립니다.
locale string 레이아웃에 저장된 값 데이터 로케일 (en, ko, ja, zh). random을 주면 레코드마다 로케일이 달라지고, 이것도 seed로 재현됩니다.
seed integer random 재현 가능한 데이터를 위한 seed. 같은 seed면 같은 결과가 나오고, 0은 seed 없음으로 칩니다.
format string json 응답 포맷 (json, csv)

객체 하나로 저장된 레이아웃, 그리고 count=1인 요청은 배열이 아니라 JSON 객체 하나로 답합니다. GET /v1/bundles/:slugseedlocale만, GET /v1/snapshots/:slug는 데이터가 이미 고정돼 있으므로 format만 받습니다.

데이터 타입

Apiryner는 30개의 내장 데이터 타입을 분류별로 제공합니다. 스키마의 type 필드로 각 필드의 생성기를 고르며, 같은 목록을 GET /v1/types로도 받을 수 있습니다.

기본

타입 설명 옵션
integer 범위 안의 랜덤 정수 min, max
decimal 랜덤 실수 min, max, precision
boolean 랜덤 true/false true_rate
string 랜덤 문자열 length, charset
enum 주어진 값 목록에서 선택 values

중첩

타입 설명 옵션
object 중첩된 JSON 객체 properties (중첩 스키마)
array 아이템 배열 items, min_items, max_items

개인 정보

타입 설명 옵션
name 사람 이름 (전체). ko/ja/zh는 성이 먼저 옵니다
email 이메일 주소. 같은 레코드에 name이 있으면 그 이름으로 만듭니다
phone 전화번호 format
address 전체 주소
city 도시 이름
zipcode 우편번호
street 번지가 붙은 도로명

텍스트

타입 설명 옵션
product_name 상품명
word 랜덤 단어
sentence 랜덤 문장
paragraph 랜덤 문단 sentences
description 설명문 length (short/medium/long)

날짜와 시간

타입 설명 옵션
date 랜덤 날짜 from, to, format
datetime 랜덤 날짜와 시각. 항상 UTC RFC 3339 형식입니다 from, to
time 랜덤 시각 format

금융

타입 설명 옵션
currency 랜덤 금액 currency, min, max
price 상품 가격 (currency와 같은 생성기) currency, min, max

식별자

타입 설명 옵션
uuid UUID v4
slug URL에 쓰기 좋은 슬러그 words
sequence 자동 증가하는 번호 start, prefix

미디어

타입 설명 옵션
image_url 랜덤 이미지 URL (플레이스홀더) width, height
color 랜덤 색상 코드 format (hex/rgb/rgba)

관계

타입 설명 옵션
reference 다른 레이아웃이 생성한 레코드에서 값을 골라옴 layout, field, fallback

관계와 조건

reference 필드

reference 필드는 다른 레이아웃이 생성한 레코드에서 값을 가져오기 때문에, 연관된 레이아웃들이 같은 키를 공유하게 됩니다. 대상 레이아웃(슬러그)과 그 레이아웃의 필드 하나를 가리키면 됩니다:

{
  "id": { "type": "uuid" },
  "user_id": {
    "type": "reference",
    "options": { "layout": "users", "field": "id" }
  }
}
  • 번들 안에서 — 레이아웃이 의존 순서대로 생성되고, reference 필드는 같은 번들 응답 안의 레코드에서 값을 고릅니다. 참조되는 레이아웃은 빠짐없이 번들에 넣으세요.
  • 개별 레이아웃 호출 — HTTP 요청은 상태가 없으므로, reference가 앞선 호출이 돌려준 레코드를 다시 쓸 수는 없습니다. 참조되는 레이아웃은 요청의 seed와 자기 배열 개수, 자기 로케일로 매번 다시 생성됩니다. 그래서 같은 seed로 두 번 호출하면 부모 레코드도 똑같고, seed가 없으면 매번 새로 나옵니다. 여러 레이아웃에 걸쳐 하나의 부모 데이터셋을 고정하고 싶다면 번들 호출로 한 번에 생성하세요.
  • 검증 — 대상 레이아웃이 계정에 실제로 있어야 하고, 지정한 필드도 그 레이아웃에 있어야 합니다. 둘 중 하나라도 어긋나면 저장이 거부됩니다. API도, 웹 에디터도 마찬가지입니다.
  • 순환 — 서로를(직접이든 건너서든) 참조하는 레이아웃은 저장할 때 거부되고 생성도 실패합니다.
  • 참조된 레이아웃에 생성된 레코드가 없으면 fallback이 대신 나옵니다.

조건부 필드

어떤 필드든 condition을 달 수 있습니다. 같은 레코드에서 먼저 생성된 필드를 보고, 레코드마다 이 필드를 포함할지 말지를 정합니다:

{
  "status": { "type": "enum", "options": { "values": ["active", "banned"] } },
  "banned_reason": {
    "type": "sentence",
    "condition": { "field": "status", "equals": "banned" }
  }
}
연산자 의미
equals / not_equals 참조한 필드와 정확히 일치하는지 아무 값
in / not_in 목록에 들어 있는지 값의 배열
gt / gte / lt / lte 숫자 비교 숫자

조건이 맞지 않으면 그 레코드에서는 필드가 아예 빠집니다. condition의 field는 같은 객체 안의 필드를 가리켜야 합니다.

번들과 스냅샷

번들

번들은 내 레이아웃 여러 개를 묶어 한 응답으로 함께 생성합니다. 그래서 reference 필드가 실제로 받은 레코드를 가리키게 됩니다.

curl -H "X-API-Key: ak_your_key_here" \
  "https://api.apiryner.com/v1/bundles/shop?seed=42"

응답은 레이아웃 슬러그를 키로 하는 객체입니다:

{
  "users": [
    { "id": "8f0c1d2e-4b77-4c2a-9c31-2a7d0f6b1e55", "name": "Sarah Johnson" }
  ],
  "orders": [
    { "id": "b1a70c93-2f18-49d6-8f0a-6c5e2b9d4471",
      "user_id": "8f0c1d2e-4b77-4c2a-9c31-2a7d0f6b1e55", "total": 41.5 }
  ]
}
  • 레이아웃은 의존 순서대로 생성되므로 reference는 항상 대상의 레코드를 보게 됩니다.
  • 번들 바깥의 레이아웃을 참조하면 그 레이아웃 키에만 error가 담기고, 나머지는 그대로 생성됩니다.
  • 레코드 수는 번들의 config에서, 없으면 각 레이아웃 자체 설정에서 가져오며 플랜 한도로 잘립니다.
  • seedlocale은 번들 전체에 적용됩니다. count 파라미터와 CSV 출력은 없습니다.

묶을 레이아웃 ID로 번들을 만듭니다:

curl -X POST https://api.apiryner.com/v1/bundles \
  -H "Authorization: Bearer oat_your_token" \
  -H "Content-Type: application/json" \
  -d '{"name": "Shop", "slug": "shop", "layout_ids": [12, 13]}'

스냅샷

스냅샷은 생성된 데이터 한 벌을 고정해서, 호출할 때마다 똑같은 응답을 돌려줍니다. 데모·스크린샷·바뀌면 안 되는 픽스처에 씁니다.

curl -X POST https://api.apiryner.com/v1/snapshots \
  -H "Authorization: Bearer oat_your_token" \
  -H "Content-Type: application/json" \
  -d '{"layout_slug": "users", "name": "Demo users",
       "slug": "demo-users", "count": 20, "seed": 42}'
  • GET /v1/snapshots/:slug가 저장된 데이터를 서빙하고, ?format=csv도 레이아웃과 똑같이 동작합니다.
  • shapeauto(기본), object, array — 는 스냅샷이 객체 하나로 답할지 배열로 답할지를 정합니다. auto는 레이아웃 설정을 따릅니다.
  • PUT /v1/snapshots/:slugname이나 data를 교체할 수 있어, 고정된 레코드를 직접 손볼 수 있습니다.
  • 스냅샷 서빙도 월 레코드 한도에 그대로 반영됩니다. 고정된 데이터도 API가 내보내는 데이터이기 때문입니다.

웹훅

HTTP(S) URL을 계정 이벤트에 구독시킵니다. 생성 응답에 서명용 secret이 한 번만 담기고, 이후로는 다시 조회할 수 없습니다.

curl -X POST https://api.apiryner.com/v1/webhooks \
  -H "Authorization: Bearer oat_your_token" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/hooks/apiryner",
       "events": ["layout.updated", "usage.warning"]}'

layout_ids를 주면 레이아웃 이벤트를 특정 레이아웃으로 제한하고, 생략하면 모든 레이아웃에 대해 받습니다.

이벤트

이벤트 발생 시점
layout.created 레이아웃이 생성될 때 — API·웹 편집기·MCP 도구 호출 어디서든
layout.updated 레이아웃의 이름·슬러그·스키마·생성 기본값이 바뀔 때
layout.deleted 레이아웃이 삭제될 때
snapshot.created 스냅샷이 고정될 때
snapshot.deleted 스냅샷이 삭제될 때
bundle.created 번들이 생성될 때
usage.warning 이번 달 요청 수나 레코드 수가 한도의 80%를 넘을 때
usage.limit_reached 이번 달 요청 수나 레코드 수가 한도에 도달할 때

전송과 검증

전송은 JSON POST이고 헤더 두 개가 붙습니다. X-Apiryner-Event에는 이벤트 이름이, X-Apiryner-Signature에는 원본 요청 본문을 시크릿으로 HMAC-SHA256 해서 16진수로 인코딩한 값이 담깁니다. 페이로드를 믿기 전에 먼저 검증하세요:

const expected = crypto
  .createHmac("sha256", secret)
  .update(rawBody)          // the raw body, before JSON.parse
  .digest("hex");

if (expected !== req.headers["x-apiryner-signature"]) {
  return res.status(401).end();
}

전송 타임아웃은 10초입니다. 네트워크 오류와 408·429·5xx 응답은 5초, 30초 뒤 두 번 재시도하고, 그 밖의 4xx는 재시도하지 않습니다. 모든 시도가 기록되며 GET /v1/webhooks/:id/deliveries로 확인할 수 있습니다.

옵션 레퍼런스

스키마의 각 필드는 type과 선택적인 options 객체를 가집니다.

스키마 필드 구조:

{
  "field_name": {
    "type": "integer",
    "options": {
      "min": 1,
      "max": 100
    }
  }
}

풀에서 값을 뽑는 모든 타입 — name, email, phone, 주소 계열, 텍스트 계열, slug — 은 locale 옵션도 받습니다. 그 필드에서만 요청 로케일을 덮어씁니다. 로케일을 덮어쓴 필드는 레코드의 인물을 공유하지 않고 자기 인물을 따로 만듭니다:

{
  "name": {"type": "name"},
  "korean_name": {"type": "name", "options": {"locale": "ko"}}
}

중첩 객체 예시:

{
  "address": {
    "type": "object",
    "properties": {
      "street": {"type": "street"},
      "city": {"type": "city"},
      "zipcode": {"type": "zipcode"}
    }
  }
}

배열 예시:

{
  "tags": {
    "type": "array",
    "items": {"type": "word"},
    "options": {"min_items": 2, "max_items": 5}
  }
}

enum 예시:

{
  "status": {
    "type": "enum",
    "options": {
      "values": ["active", "inactive", "pending"]
    }
  }
}

오류와 한도

오류는 error 코드와, 대개 사람이 읽을 수 있는 message가 담긴 JSON으로 돌아옵니다:

{
  "error": "forbidden",
  "message": "API keys are read-only. Use an OAuth Bearer token for write operations."
}
상태 error 발생 상황
400 invalid request 잘못된 본문, 규칙에 맞지 않는 슬러그, 생성기가 읽을 수 없는 스키마
401 unauthorized 자격 증명이 없거나 유효하지 않거나 비활성·폐기됨
403 forbidden API 키로 쓰기를 시도함 — API 키는 읽기 전용
403 insufficient_scope OAuth 토큰에 read 또는 write 스코프가 없음 (WWW-Authenticate 헤더로도 전달)
403 layout_limit_reached 플랜의 레이아웃 개수 한도에 이미 도달함
404 <리소스> not found 해당 슬러그의 레이아웃·번들·스냅샷·템플릿이 계정에 없음
429 rate_limit_exceeded 분당 요청 속도 초과 — Retry-After에 재시도 시점이 담김
429 quota_exceeded 이번 달 요청 수 또는 레코드 수 한도를 모두 소진함

속도 제한과 사용량

모든 응답에 분당 사용 한도가 함께 실립니다:

  • X-RateLimit-Limit — 플랜의 분당 허용 요청 수
  • X-RateLimit-Remaining — 현재 창에서 남은 요청 수
  • X-RateLimit-Reset — 창이 리셋되는 시각 (Unix 타임스탬프)
  • Retry-After — 기다릴 초. 429일 때만 붙습니다

월 사용량은 요청 수와 레코드 수 두 축으로 집계합니다. 번들 호출은 요청 1건에 더해 응답에 담긴 레코드 전부가 반영됩니다. 이번 기간 사용량은 GET /v1/account/usage로 확인합니다:

{
  "requests": 128,
  "records": 4210,
  "limit_requests": 1000,
  "limit_records": 10000,
  "period": "2026-08"
}

플랜의 요청당 최대 레코드 수를 넘는 count는 거절되지 않고 잘립니다. 너무 많이 요청했다는 이유로 실패하지는 않습니다. 레이아웃 개수·API 키 개수·중첩 깊이 한도도 같은 방식으로 사용 시점에 적용됩니다.

MCP 서버

Claude Code, Cursor, Claude Desktop 같은 AI 코딩 에이전트가 Model Context Protocol 툴 호출만으로 목 데이터를 만들고 레이아웃을 관리할 수 있습니다. 호스팅된 엔드포인트에 붙이거나, CLI로 로컬에서 띄우면 됩니다.

원격 서버 — 설치할 것이 없습니다

호스팅된 엔드포인트를 에이전트에 알려주고 브라우저에서 승인하면 끝입니다. npm 패키지도, 복사해 넣을 API 키도 필요 없습니다.

claude mcp add --transport http apiryner https://api.apiryner.com/mcp

에이전트가 인증이 필요하다고 알리면, 브라우저에서 승인하는 것이 설정의 전부입니다. 브라우저 대신 API 키를 쓰려면:

claude mcp add --transport http apiryner https://api.apiryner.com/mcp \
  --header "X-API-Key: ak_your_key_here"

로컬 서버

apiryner CLI가 내 컴퓨터에서 서버를 띄웁니다. 스키마 관련 툴은 계정 없이 오프라인에서도 돕니다.

Claude Code에 추가하기:

claude mcp add apiryner -- npx apiryner mcp

JSON(mcpServers)으로 설정하는 클라이언트라면:

{
  "mcpServers": {
    "apiryner": {
      "command": "npx",
      "args": ["apiryner", "mcp"],
      "env": { "APIRYNER_API_KEY": "ak_your_key_here" }
    }
  }
}

인증 인자
list_types 선택
validate_schema schema
infer_schema input, type
quick_generate schema, count, seed
list_layouts 필요 limit, offset
create_layout 필요 name, slug, schema, locale, is_array, array_count
update_layout 필요 slug + 바꿀 필드들
delete_layout 필요 slug
generate 필요 slug, count, seed, locale, format
generate_bundle 필요 slug
get_snapshot 필요 slug

infer_schemagenerate_bundle은 아직 로컬 서버에만 있습니다.

인증

validate_schema, infer_schema, quick_generate는 전부 로컬에서 돕니다 — 계정도 네트워크도 필요 없습니다. 가입 전에도 에이전트가 픽스처를 만들거나 OpenAPI 파일을 레이아웃 스키마로 바꿀 수 있습니다.

list_types는 에이전트가 없는 필드 타입을 지어내지 않게 막아 줍니다. 인증된 상태면 이 페이지의 타입 카탈로그를 설명과 지원 로케일까지 담아 돌려주고, 인증이 없으면 실패하는 대신 패키지에 내장된 타입 이름 목록으로 폴백합니다.

원격 서버는 브라우저로 인증합니다. 에이전트가 스스로 등록하고, 한 번 승인하면, 발급된 토큰은 이 엔드포인트 전용으로 묶입니다. X-API-Key 헤더도 쓸 수 있고, 이때는 API 키의 읽기 전용 제한이 그대로 적용됩니다.

로컬 서버의 크리덴셜은 API가 필요한 첫 툴 호출 때 다음 순서로 해석됩니다.

  1. apiryner mcp 뒤에 붙인 --key <key>, 또는 $APIRYNER_API_KEY
  2. apiryner login으로 만든 OAuth 세션 (만료되면 자동 갱신)
  3. apiryner config set api-key <key>로 저장한 API 키

인증 없이 서버를 띄워도 괜찮습니다. 계정이 필요한 툴은 무엇이 빠졌는지 알려주고, 로그인하는 순간부터 재시작 없이 동작합니다. create_layout, update_layout, delete_layout은 계정에 쓰고, 삭제는 되돌릴 수 없다는 점만 유의하세요.