/me계정과 남은 Pixo
응답
{
"success": true,
"data": {
"id": "0f8b2d14-9c3a-4e21-b7d5-6a1e0c9f4b32",
"email": "you@studio.com",
"role": "user",
"pixo_balance": 320,
"created_at": "2026-07-02T11:20:04.118Z"
}
}빌드 스크립트·CI·게임 서버에서, 또는 코딩 에이전트에게 시켜서 DotForge 를 부릅니다. 브라우저에서 쓰는 것과 같은 엔진이고, 다른 것은 자격증명뿐입니다.
Claude Code·Codex 같은 코딩 에이전트에게 시킬 거라면, 규칙 파일을 저장소에 넣어 두세요. 이 페이지의 규칙 중 에이전트가 첫 요청을 성공시키는 데 필요한 것만 골라 담아 우리가 배포합니다 — 손으로 옮겨 적은 사본은 규칙이 바뀔 때 뒤처지고, 그 실패는 우리 로그에 남지 않습니다.
AGENTS.md — Codex·Cursor·Copilot 을 비롯해 대부분이 저장소 루트에서 이 이름을 찾는다.
curl -O https://dotforge.cc/AGENTS.mdCLAUDE.md — Claude Code 가 찾는 이름. 내용은 위와 같다.
curl -O https://dotforge.cc/CLAUDE.mdClaude Code 스킬 — 도트·스프라이트 이야기가 나올 때 알아서 열린다. 규칙을 미리 안 읽어도 된다.
curl --create-dirs -o .claude/skills/dotforge/SKILL.md https://dotforge.cc/skill/SKILL.md이 페이지도 로그인 없이 열립니다 — 주소만 줘도 에이전트가 읽습니다. 값이 필요할 때 읽을 곳은 GET /catalog 이고 그것도 인증 없이 열립니다. 사이트 지도는 /llms.txt 에 있습니다.
파일을 넣을 수 없는 자리(웹 채팅 등)에는 같은 규칙을 문단으로 붙여넣으세요.
DotForge API 로 도트 스프라이트를 만들어 줘.
아래 규칙을 지켜라. 더 필요하면 https://dotforge.cc/docs 를 읽어라 (로그인 없이 열린다).
## 인증
헤더 하나다.
```
Authorization: Bearer $DOTFORGE_KEY
```키는 어느 쪽에도 넣지 마세요. 환경변수 DOTFORGE_KEY 로 두고 그 이름만 알려 주면 됩니다 — 대화 기록과 소스에 원문이 남지 않습니다. 키는 설정에서 발급합니다.
모든 주소는 이 밑에 붙습니다. 키는 설정에서 발급하고, 발급 화면을 닫으면 다시 볼 수 없습니다.
https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1인증은 헤더 하나입니다. console 의 JWT 는 여기서 통하지 않습니다 — 문이 다릅니다.
Authorization: Bearer dotforge_sk_...응답은 언제나 { success: true, data } 또는 { success: false, error } 입니다. 아래 예시는 data 까지 포함한 전문입니다.
그림 한 장을 굽는 데 수십 초가 걸립니다. 그동안 연결을 붙잡고 있으면 함수 실행 한도에 먼저 걸리기 때문에, POST 는 잡을 접수하고 바로 돌아옵니다. 결과는 폴링으로 받습니다.
curl -X POST "https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1/assets" \
-H "Authorization: Bearer $DOTFORGE_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt":"버섯 갑옷을 입은 작은 전사","kind":"character"}'curl "https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1/jobs" -H "Authorization: Bearer $DOTFORGE_KEY"기본은 진행 중인 것만 옵니다. status 가 done 이 되면 그 에셋을 다시 읽어 새 이미지를 찾습니다.
curl "https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1/assets/$ASSET_ID" -H "Authorization: Bearer $DOTFORGE_KEY"
curl "https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1/images/$IMAGE_ID/download" -H "Authorization: Bearer $DOTFORGE_KEY"짧은 수명의 서명 URL 이 옵니다. 애니메이션 시트면 frames 도 같이 오므로 엔진에 넣을 때 격자를 다시 추론하지 않아도 됩니다.
사용 내역과 키 발급은 없습니다. 앞엣것은 결제 기록이라 사람이 보는 화면이고, 뒤엣것은 키로 키를 만들 수 있으면 유출된 키 하나가 스스로 자기 자리를 늘리기 때문입니다. 그 밖에는 브라우저가 하는 일을 전부 할 수 있습니다.
누구인지, 얼마가 남았는지, 굽는 기계가 살아 있는지.
/me계정과 남은 Pixo
{
"success": true,
"data": {
"id": "0f8b2d14-9c3a-4e21-b7d5-6a1e0c9f4b32",
"email": "you@studio.com",
"role": "user",
"pixo_balance": 320,
"created_at": "2026-07-02T11:20:04.118Z"
}
}/catalog인증 불필요고를 수 있는 값 전부
코드에 상수로 박지 마세요. 종류가 늘면 이 응답이 같이 늘고, 화면에도 이 페이지에도 여기서 온 값만 그립니다. 아래 값 사전이 지금 이 엔드포인트의 응답을 그린 것입니다.
{
"success": true,
"data": {
"kinds": [
{
"id": "character",
"aspects": ["square", "tall"],
"poses": ["idle", "walk", "attack"],
"animatable": true,
"cell_sizes": [64, 96, 128, 192, 256, 384, 512],
"default_cell_size": 128,
"outlines": ["off", "light", "normal", "strong"],
"scale_axis": "height",
"views": ["front", "back", "left", "right"],
"shots": ["full", "bust", "face"],
"generate_cost": 4
}
],
"poses": [{ "id": "walk", "frames": 4, "fps": 8 }],
"aspects": [
{
"id": "tall",
"cell_width": 3,
"cell_height": 4,
"frames": 1,
"cell_sizes": null,
"default_cell_size": null
}
],
"cell_sizes": [64, 96, 128, 192, 256, 384, 512],
"palette_sizes": [8, 16, 24, 32, 48],
"outlines": ["off", "light", "normal", "strong"],
"subject_scales": [70, 80, 90, 100],
"defaults": {
"kind": "character",
"aspect": "square",
"cell_size": 128,
"palette_size": 24,
"outline": "normal"
}
}
}/system/status러너가 살아 있나 · 큐에 몇 개 있나
잡이 안 움직일 때 우리 쪽인지 내 쪽인지 가르는 값입니다. runner_seen_at 이 한참 전이면 굽는 기계가 멈춘 것이고, 그 판정은 클라이언트가 합니다 — 그래서 서버 시각(now)을 같이 줍니다. 기기 시계가 몇 분씩 어긋난 경우가 실제로 있습니다.
{
"success": true,
"data": {
"runner_seen_at": "2026-08-13T11:29:54.207Z",
"queued": 2,
"processing": 1,
"now": "2026-08-13T11:29:58.664Z"
}
}에셋을 담는 그릇이자 스타일 계약이 붙는 자리입니다. 같은 프로젝트에서 만든 것은 같은 아트 스타일·색 수·테두리·피사체 크기를 물려받습니다.
/projects프로젝트 목록
기본 프로젝트가 맨 앞입니다. 안 고르면 에셋이 거기로 들어가는 자리라, 목록에서도 그 자리에 있어야 헷갈리지 않습니다. 가입할 때 하나가 자동으로 만들어지므로 목록이 비는 일은 없습니다.
{
"success": true,
"data": {
"projects": [
{
"id": "b52d7f36-8e01-4c94-a6b3-19f8d0e47c25",
"name": "기본 프로젝트",
"color": "gray",
"style_contract": { "subjectScale": 100 },
"base_prompt": null,
"is_default": true,
"asset_count": 12,
"created_at": "2026-07-02T11:20:04.118Z",
"updated_at": "2026-07-02T11:20:04.118Z"
}
]
}
}/projects프로젝트를 만든다
빌드 스크립트가 “이번 게임의 에셋” 을 한 그릇에 모으고 그 그릇에 아트 스타일을 걸어 두는 자리입니다. 만든 뒤 POST /assets 에 project_id 를 실으면 그 프로젝트로 들어가고, 계약도 같이 걸립니다.
| 타입 | 설명 | |
|---|---|---|
name필수 | string | 80자까지 |
color | enum | rose · orange · amber · lime · emerald · teal · sky · indigo · violet · gray. 안 주면 gray. 목록에서 점으로만 쓰이고 그림에는 영향이 없습니다 |
base_prompt | string | 이 프로젝트의 모든 프롬프트 앞에 붙는 공통 첫 문장. 500자까지 |
style_contract | object | 아래 표 |
| 키 | 값 | 어디로 가나 |
|---|---|---|
artStyle | 문자열 300자 | 프롬프트 |
notes | 문자열 300자 | 프롬프트 |
paletteSize | 값 사전 | 후처리 |
outline | 값 사전 | 후처리 |
subjectScale | 70 · 80 · 90 · 100 | 후처리 |
subjectScale 은 요청이 덮어쓸 수 없습니다. 이 값이 하는 일이 “이 프로젝트의 에셋은 서로 같은 크기다” 라서, 한 장만 다르게 고를 수 있으면 보장이 아니라 기본값이 됩니다. 안 주면 만들 때 100 이 붙습니다paletteSize·outline 은 요청이 덮어쓸 수 있습니다. 지금 고른 것이 더 구체적이니까요curl -X POST "https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1/projects" \
-H "Authorization: Bearer $DOTFORGE_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "던전 크롤러",
"color": "violet",
"base_prompt": "어두운 지하 던전의 색조",
"style_contract": {
"artStyle": "16비트 SNES 도트",
"paletteSize": 24,
"outline": "normal",
"subjectScale": 90
}
}'{
"success": true,
"data": {
"id": "b52d7f36-8e01-4c94-a6b3-19f8d0e47c25",
"name": "던전 크롤러",
"color": "violet",
"style_contract": {
"artStyle": "16비트 SNES 도트",
"paletteSize": 24,
"outline": "normal",
"subjectScale": 90
},
"base_prompt": "어두운 지하 던전의 색조",
"is_default": false,
"created_at": "2026-08-13T11:40:22.017Z",
"updated_at": "2026-08-13T11:40:22.017Z"
}
}/projects/:id이름 · 색 · 공통 문장 · 스타일 계약
style_contract 는 병합이 아니라 통째로 갈아끼웁니다. 한 키만 바꾸려면 나머지도 같이 보내세요 — 안 그러면 빠뜨린 키가 지워집니다. {"paletteSize":32} 만 보내면 artStyle 도 outline 도 사라집니다.
특히 subjectScale 을 빠뜨리지 마세요. 이 값만은 요청으로 되돌릴 수 없어서, 여기서 지워지면 그 프로젝트는 피사체 크기를 안 맞추는 상태로 남고 다시 PATCH 하기 전까지 그대로입니다. 계약을 고쳐도 이미 만들어진 그림은 그대로입니다; 다음에 굽는 것부터 새 계약을 따릅니다.
| 타입 | 설명 | |
|---|---|---|
name | string | 빈 문자열은 거절됩니다 |
color | enum | 없는 색은 거절됩니다 |
base_prompt | string | null | 빈 문자열을 주면 지웁니다 |
style_contract | object | 키는 POST /projects 와 같습니다. {} 를 주면 계약이 비고, 그 프로젝트의 에셋은 기본값으로 굽습니다 |
curl -X PATCH "https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1/projects/b52d7f36-8e01-4c94-a6b3-19f8d0e47c25" \
-H "Authorization: Bearer $DOTFORGE_KEY" \
-H "Content-Type: application/json" \
-d '{"style_contract":{"artStyle":"16비트 SNES 도트","paletteSize":32,"subjectScale":90}}'{
"success": true,
"data": {
"id": "b52d7f36-8e01-4c94-a6b3-19f8d0e47c25",
"name": "던전 크롤러",
"color": "violet",
"style_contract": {
"artStyle": "16비트 SNES 도트",
"paletteSize": 32,
"subjectScale": 90
},
"base_prompt": "어두운 지하 던전의 색조",
"is_default": false,
"updated_at": "2026-08-13T11:42:09.554Z"
}
}/projects/:id프로젝트만 지운다
안의 에셋은 사라지지 않습니다. 지우기 직전에 기본 프로젝트로 옮겨집니다 — 그릇을 치우는 것이지 그림을 지우는 것이 아닙니다. 그림을 지우려면 DELETE /assets/:id 를 하나씩 부르세요.
기본 프로젝트(is_default: true)는 지울 수 없습니다 — 이관 대상이 사라지면 남은 에셋이 갈 곳이 없어집니다.
{
"success": true,
"data": { "deleted": true }
}에셋은 메타데이터고(“버섯 전사”) 그림은 그 안에 쌓입니다. 리롤도 반전도 시트도 전부 같은 에셋의 이미지 한 줄입니다.
/assets라이브러리
카드 한 장이 에셋 하나입니다. 이미지를 전부 싣지 않고 커버 한 장과 개수만 옵니다 — 그림이 필요하면 GET /assets/:id 입니다.
| 타입 | 설명 | |
|---|---|---|
limit | number | 기본 50, 최대 100 |
favorite | "true" | 즐겨찾기만 |
project_id | uuid | 안 주면 전체 프로젝트를 합쳐서 봅니다 |
curl "https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1/assets?limit=20&favorite=true" \
-H "Authorization: Bearer $DOTFORGE_KEY"{
"success": true,
"data": {
"assets": [
{
"id": "0f8b2d14-9c3a-4e21-b7d5-6a1e0c9f4b32",
"project_id": "…",
"name": "버섯 전사",
"prompt": "버섯 갑옷을 입은 작은 전사",
"kind": "character",
"cell_size": 128,
"aspect": "tall",
"cover_image_id": "7c4e9a02-15bd-4a86-8f31-2d90e5b7c184",
"is_favorite": true,
"uses_project_style": true,
"created_at": "2026-08-12T09:03:11.402Z",
"updated_at": "2026-08-12T09:04:52.881Z",
"image_count": 4,
"active_job_count": 1,
"cover_url": "https://… (5분)"
}
],
"count": 1
}
}/assets4 Pixo에셋을 만들고 첫 그림을 굽는다
두 단계로 나누지 않습니다. “에셋 만들기” 가 따로 있으면 그림 한 장을 보기 전에 이름부터 지어야 하는데, 아직 뭐가 나올지 모르는 시점입니다. 에셋 행과 잡이 같이 생깁니다 — 잔액이 모자라 잡이 서지 못하면 만들던 에셋도 지웁니다.
| 타입 | 설명 | |
|---|---|---|
prompt필수 | string | 1000자까지 |
kind | enum | 안 주면 character. 값 사전 |
aspect | enum | 에셋이 소유합니다 — 여기서 한 번 고르고, 이후 요청에는 싣지 않습니다. 그 종류가 못 쓰는 값이면 첫 번째 값으로 떨어집니다 |
cell_size | number | 종류와 비율이 같이 정합니다. 못 고르는 값은 기본값으로 떨어집니다 |
name | string | 안 주면 프롬프트 앞 80자 |
project_id | uuid | 안 주면 기본 프로젝트 |
use_project_style | boolean | 프로젝트 스타일 계약을 따를지. false 를 명시할 때만 끕니다. 이 값은 에셋에 남아 리롤에도 따라갑니다 |
palette_size | number | 색 수. 안 주면 프로젝트 계약, 계약에도 없으면 기본값. 고를 수 있는 값은 값 사전 |
outline | string | 테두리 세기. 종류가 테두리를 안 쓰면 무엇을 줘도 off |
curl -X POST "https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1/assets" \
-H "Authorization: Bearer $DOTFORGE_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "버섯 갑옷을 입은 작은 전사",
"kind": "character",
"aspect": "tall",
"cell_size": 128
}'{
"success": true,
"data": {
"asset": {
"id": "0f8b2d14-9c3a-4e21-b7d5-6a1e0c9f4b32",
"name": "버섯 갑옷을 입은 작은 전사",
"kind": "character",
"cell_size": 128,
"aspect": "tall",
"cover_image_id": null,
"is_favorite": false,
"uses_project_style": true,
"created_at": "2026-08-12T09:03:11.402Z",
"updated_at": "2026-08-12T09:03:11.402Z"
},
"job_id": "3ab61f58-70c2-4d19-9e45-8b0fa2c61d77",
"status": "pending",
"pixo_cost": 4
}
}/assets/:id에셋 + 그림 전부 + 진행 중인 잡
images[] 는 오래된 순입니다 — 첫 칸이 유저가 처음 본 그림 입니다. preview_url 은 5분짜리라 저장해 두면 안 되고, 받아 갈 때는 /images/:id/download 를 부릅니다.
{
"success": true,
"data": {
"id": "0f8b2d14-9c3a-4e21-b7d5-6a1e0c9f4b32",
"name": "버섯 전사",
"prompt": "버섯 갑옷을 입은 작은 전사",
"kind": "character",
"cell_size": 128,
"aspect": "tall",
"cover_image_id": "7c4e9a02-15bd-4a86-8f31-2d90e5b7c184",
"is_favorite": false,
"uses_project_style": true,
"images": [
{
"id": "7c4e9a02-15bd-4a86-8f31-2d90e5b7c184",
"asset_id": "0f8b2d14-9c3a-4e21-b7d5-6a1e0c9f4b32",
"op": "generate",
"parent_image_id": null,
"label": null,
"palette": [{ "hex": "#3b2a4d", "count": 812 }],
"width": 96,
"height": 128,
"frames": 1,
"meta": {},
"pixo_cost": 4,
"preview_url": "https://… (5분)",
"resizable": true,
"source_expires_at": "2026-09-11T09:04:52.881Z",
"expires_at": "2026-11-10T09:04:52.881Z",
"created_at": "2026-08-12T09:04:52.881Z"
}
],
"active_jobs": [
{
"id": "3ab61f58-70c2-4d19-9e45-8b0fa2c61d77",
"op": "animate",
"status": "processing",
"progress": 40,
"progress_note": "walk 행 굽는 중",
"error_message": null,
"created_at": "2026-08-12T09:10:02.114Z"
}
],
"animatable": true,
"poses": ["idle", "walk", "attack"]
}
}/assets/:id이름 · 커버 · 즐겨찾기 · 프로젝트
하나 이상 주세요 — 빈 요청은 VALIDATION_ERROR 입니다. 프로젝트를 옮기면 이후 리롤·애니메이션이 새 프로젝트의 계약을 따릅니다.이미 만들어진 그림은 그대로입니다 — 옮겼다고 다시 굽지 않습니다.
| 타입 | 설명 | |
|---|---|---|
name | string | 빈 문자열은 거절됩니다 |
is_favorite | boolean | |
cover_image_id | uuid | 이 에셋의 이미지여야 합니다 |
project_id | uuid | 다른 프로젝트로 옮깁니다 |
use_project_style | boolean | 만든 뒤에도 켜고 끌 수 있습니다 |
curl -X PATCH "https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1/assets/0f8b2d14-9c3a-4e21-b7d5-6a1e0c9f4b32" \
-H "Authorization: Bearer $DOTFORGE_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"버섯 전사","is_favorite":true}'{
"success": true,
"data": {
"id": "0f8b2d14-9c3a-4e21-b7d5-6a1e0c9f4b32",
"name": "버섯 전사",
"is_favorite": true,
"updated_at": "2026-08-13T11:31:02.900Z"
}
}/assets/:id안의 그림과 파일까지. 되돌릴 수 없다
{
"success": true,
"data": { "deleted": true }
}/assets/:id/imagesop 마다 다름같은 에셋에 그림 한 장 더
여섯 갈래가 이 하나로 들어갑니다.에셋은 메타데이터고(“버섯 전사”) 그림은 그 안에 쌓입니다 — 리롤도 반전도 시트도 전부 같은 에셋의 이미지 한 줄입니다. 응답은 여섯 갈래가 모두 같습니다.
| 타입 | 설명 | |
|---|---|---|
op필수 | enum | 아래 표 |
parent_image_id | uuid | generate 를 뺀 전부에 필요합니다. 이 에셋의 이미지여야 하고, 아직 굽는 중인 그림은 부모가 될 수 없습니다 |
label | string | 어느 op 든 선택. 안 주면 op 마다 정해진 이름이 붙습니다 |
palette_size | number | 색 수. 안 주면 프로젝트 계약, 계약에도 없으면 기본값. 고를 수 있는 값은 값 사전 |
outline | string | 테두리 세기. 종류가 테두리를 안 쓰면 무엇을 줘도 off |
| op | 이 op 만 받는 값 | Pixo |
|---|---|---|
generate | prompt (안 주면 에셋의 프롬프트 그대로 = 리롤) | 4 |
revise | view · shot · prompt 중 하나 이상 | 4 |
mirror | 없음 | 0 |
recolor | source_color · target_color (#RRGGBB) | 0 |
resize | cell_size | 0 |
animate | poses[] · action(자세 하나일 때만) | 자세당 8 |
mirror·recolor·resize 가 0 인 것은 할인이 아니라 원가가 0 이기 때문입니다 — 모델을 부르지 않고 픽셀만 건드립니다.
카메라를 옮기는 일은 전부 revise 입니다 — 부모를 레퍼런스로 붙여서 각도만 바꾸기 때문입니다. 시선은 front(정면) · front_quarter(우앞대각) · side(우측면) · back_quarter(우뒷대각) · back(후면) · back_quarter_left(좌뒷대각) · side_left(좌측면) · front_quarter_left(좌앞대각), 컷은 full(전신) · bust(상반신) · face(얼굴). 레퍼런스 없이 각도만 바꾸면 각도는 맞아도 매번 다른 사람이 나옵니다.
frames > 1)는 revise·animate·resize 의 부모가 될 수 없습니다. 워커가 시트를 한 장짜리 그림으로 보고 다시 그리므로 격자가 통째로 레퍼런스가 됩니다resize 는 축소 전 원본이 남아 있는 30일 안에서만 됩니다(images[].resizable). 같은 크기로 다시 뽑는 것도 거절합니다recolor 의 source_color 는 그 이미지의 팔레트에서 계열을 찾습니다. 다른 그림의 색을 넣으면 못 찾고 거절합니다 — 이미지마다 따로 양자화돼서 같은 파랑이라도 값이 몇 단위 다릅니다generate 에 view 를 실으면 거절합니다. 시선은 revise 로 옮겨 갔습니다animate 의 poses[] 는 그 종류가 허용하는 것만 남기고, 하나도 안 남으면 거절합니다. action 은 자세를 하나만 보낼 때만 쓸 수 있습니다 — 여러 자세에 문장 하나면 어느 자세를 말하는지 알 수 없습니다# 리롤
curl -X POST "https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1/assets/0f8b2d14-9c3a-4e21-b7d5-6a1e0c9f4b32/images" \
-H "Authorization: Bearer $DOTFORGE_KEY" \
-H "Content-Type: application/json" \
-d '{"op":"generate"}'
# 뒷모습 — 부모를 ref 로 붙인다
-d '{"op":"revise","parent_image_id":"7c4e9a02-15bd-4a86-8f31-2d90e5b7c184","view":"back"}'
# 좌우반전 (0 Pixo)
-d '{"op":"mirror","parent_image_id":"7c4e9a02-15bd-4a86-8f31-2d90e5b7c184"}'
# 색 갈아입히기 (0 Pixo)
-d '{"op":"recolor","parent_image_id":"7c4e9a02-15bd-4a86-8f31-2d90e5b7c184",
"source_color":"#3b2a4d","target_color":"#1f4d3b"}'
# 걷기 시트
-d '{"op":"animate","parent_image_id":"7c4e9a02-15bd-4a86-8f31-2d90e5b7c184","poses":["walk"]}'{
"success": true,
"data": {
"job_id": "3ab61f58-70c2-4d19-9e45-8b0fa2c61d77",
"status": "pending",
"pixo_cost": 4
}
}/images/:id그림 한 장
커버로 걸려 있었으면 커버가 null 로 돌아가고, 목록 조회가 가장 오래된 그림으로 대신 채웁니다.
{
"success": true,
"data": { "deleted": true }
}/images/:id/download서명 URL
15분짜리입니다. 아직 굽는 중인 그림은 NOT_FOUND 입니다 — 잡이 done 이 된 뒤에 부르세요.
{
"success": true,
"data": {
"url": "https://…",
"expires_in": 900,
"frames": 4,
"width": 384,
"height": 128
}
}/jobs진행 중(기본) 또는 끝난 것까지
이 문에는 실시간 신호가 없으므로 폴링이 정답입니다. 분당 한도(120)가 그 폴링을 감당하도록 잡혀 있습니다. status 는 pending · processing · done · failed · cancelled 입니다.
| 타입 | 설명 | |
|---|---|---|
active | "false" | 끝난 것까지 최근 50건. 기본은 진행 중인 것만 |
curl "https://sfrdtlqdcuwrlpvfkdxy.supabase.co/functions/v1/api/v1/jobs?active=false" \
-H "Authorization: Bearer $DOTFORGE_KEY"{
"success": true,
"data": {
"jobs": [
{
"id": "3ab61f58-70c2-4d19-9e45-8b0fa2c61d77",
"asset_id": "0f8b2d14-9c3a-4e21-b7d5-6a1e0c9f4b32",
"op": "generate",
"status": "done",
"progress": 100,
"progress_note": null,
"error_code": null,
"error_message": null,
"pixo_cost": 4,
"created_at": "2026-08-12T09:03:11.402Z",
"completed_at": "2026-08-12T09:04:52.881Z"
}
]
}
}아래 표는 전부 GET /catalog 가 돌려준 값을 그대로 그린 것입니다. 코드에 상수로 박지 말고 그 엔드포인트를 읽으세요 — 종류가 늘면 여기도 같이 늡니다.
kind 가 고를 수 있는 것을 정합니다. 목록이 비어 있다는 것이 곧 “그 종류에는 없다” 는 뜻입니다 — 자세가 비면 애니메이션이, 시선이 비면 카메라 축이 없습니다.
| kind | 비율 | 크기 (기본) | 자세 | 시선·컷 |
|---|---|---|---|---|
character캐릭터 | tall · square · wide · card | 24 · 32 · 40 · 48 · 64 · 80 · 96 · 128 · 160 · 192 · 256 · 384 · 512 (128) | 8개 | 8 · 3 |
item아이템 | square | 24 · 32 · 40 · 48 · 64 · 80 · 96 · 128 · 160 · 192 · 256 · 384 · 512 (128) | — | — |
effect이펙트 | tall · square · wide · card | 24 · 32 · 40 · 48 · 64 · 80 · 96 · 128 · 160 · 192 · 256 · 384 · 512 (128) | 7개 | — |
background배경 | wide · square · tall · phone · phone_safe | 128 · 256 · 384 · 512 · 768 (384) | — | — |
tile타일 | square | 16 · 24 · 32 · 40 · 48 · 64 · 80 · 96 · 128 · 160 · 192 · 256 · 384 · 512 (128) | — | — |
etc기타 | tall · square · wide · card | 24 · 32 · 40 · 48 · 64 · 80 · 96 · 128 · 160 · 192 · 256 · 384 · 512 (128) | — | — |
aspect 는 에셋이 소유합니다. 만들 때 한 번 고르고, 이후 리롤·애니메이션 요청에는 싣지 않습니다 — 같은 에셋의 그림들이 비율이 다르면 리컬러도 시트도 서로 안 맞습니다.
| aspect | 칸 | 크기 |
|---|---|---|
tall세로 | 3 : 4 | 종류를 따름 |
square정사각 | 1 : 1 | 종류를 따름 |
wide가로 | 4 : 3 | 종류를 따름 |
card카드 | 2 : 3 | 종류를 따름 |
phone모바일 고정 | 3 : 7 | 280 · 420 · 560 · 840 (560) |
phone_safe모바일 가변 | 11 : 21 | 210 · 420 · 840 (840) |
animate 의 poses[] 에 넣는 값입니다. 종류가 허용하는 것만 통과하고, 프레임 수가 곧 시트 한 행의 칸 수입니다.
| pose | 프레임 | fps |
|---|---|---|
idle대기 | 4 | 4 |
walk걷기 | 4 | 8 |
attack공격 | 4 | 8 |
jump점프 | 4 | 8 |
wave손 흔들기 | 4 | 6 |
die쓰러짐 | 4 | 6 |
run달리기 | 4 | 12 |
hurt피격 | 4 | 10 |
cast시전 | 4 | 10 |
charge충전 | 4 | 10 |
travel전개 | 4 | 12 |
projectile날아가기 | 4 | 12 |
impact착탄 | 8 | 12 |
aura오라 | 4 | 6 |
linger잔존 | 4 | 6 |
어느 op 에나 붙일 수 있습니다. 안 주면 프로젝트의 스타일 계약을 따르고, 계약에도 없으면 기본값입니다. 프롬프트로 가지 않습니다 — 그림 지시가 아니라 축소 뒤에 도는 값입니다.
| 고를 수 있는 값 | 기본 | |
|---|---|---|
palette_size | 8 · 16 · 24 · 32 · 48 | 24 |
outline | off · light · normal · strong | normal |
code 로 분기하세요 — message 는 사람이 읽는 한국어라 바뀔 수 있습니다.
{
"success": false,
"error": {
"code": "TOKEN_INSUFFICIENT",
"message": "Pixo가 모자랍니다."
}
}| code | HTTP | 언제 |
|---|---|---|
AUTH_REQUIRED | 401 | 헤더가 없다 |
AUTH_INVALID_TOKEN | 401 | 없는 키 · 폐기된 키 · 키 형식이 아님 |
VALIDATION_ERROR | 400 | 값이 카탈로그에 없거나 빠졌다 |
NOT_FOUND | 404 | 없거나 남의 것 (구분하지 않는다) |
TOKEN_INSUFFICIENT | 402 | Pixo 가 모자라 잡이 서지 않았다 |
PROJECT_LIMIT_EXCEEDED | 403 | 프로젝트가 이미 50개다 (기본 프로젝트 포함) |
PROJECT_DEFAULT_UNDELETABLE | 409 | 기본 프로젝트를 지우려 했다 |
RATE_LIMIT_EXCEEDED | 429 | 분당 한도를 넘겼다 |
INTERNAL_ERROR | 500 | 우리 쪽 문제 |
키 하나당 분당 120회입니다. 창은 60초 고정이고, 넘기면 429 가 나며 그 요청은 세지 않습니다. 폴링이 이 한도 안에서 돌도록 잡아 둔 값이라, 배치로 열두 장을 굽고 각각 확인해도 걸리지 않습니다.
유료 op 는 Pixo 잔액이 막지만 조회와 mirror·recolor 는 공짜라, 그 경로를 세우는 것은 이 한도뿐입니다. 키는 계정당 5개까지 살아 있을 수 있습니다.
| 값 | |
|---|---|
프롬프트 | 1000자 |
이름 · 라벨 | 80자 (넘으면 잘린다) |
프로젝트 | 50개 (기본 프로젝트 포함) |
base_prompt | 500자 |
artStyle · notes | 각 300자 |
GET /assets limit | 기본 50 · 최대 100 |
GET /jobs | 최근 50건 |
다운로드 URL | 15분 |
미리보기 URL | 5분 |
원본 보관 | 30일 (지나면 resize·고화질 revise 불가) |
이미지 보관 | 90일 |