Pasty 사용 안내

팀에서 직접 운영하는 가벼운 전달용 게시판. 텍스트나 파일을 올리면 6자리 공유 코드가 나오고, 코드만으로 받아가며, 기한이 지나면 자동 삭제됩니다.

사이트 pasty.youlidao.ai 2026-10-16 소스 대조 확인
MN3W2R
공유 코드는 6자리, 31자 집합에서 뽑습니다: 23456789ABCDEFGHJKMNPQRSTUVWXYZ. 헷갈리는 0/O/1/I/L 은 빼서 소리 내어 전해도 틀리지 않습니다. 입력할 때 대소문자는 가리지 않습니다.

1무엇인가

항목사실
HTML 페이지AI 에이전트용: 토큰으로 HTML 페이지 하나를 호스팅하고, 브라우저에서 바로 열리는 /p/ URL을 받습니다(§9 참고)
로그인없습니다. 만들 때도 볼 때도 인증하지 않으며, 코드를 가진 사람은 읽을 수 있습니다
내용텍스트 / 파일 하나 / 텍스트 + 파일
텍스트 상한50,000자 (JSON 엔드포인트는 본문 100KB 제한이 따로 있습니다 · §4.2)
파일 상한100 MB, 한 개, 형식 제한 없음
만료5분 / 30분 / 1시간 / 1일 / 7일, 기본값은 1일
삭제 / 수정 / 목록모두 없습니다. 만든 뒤에는 되돌릴 수 없고 만료를 기다려야 합니다
저장메타데이터와 텍스트는 Redis(TTL 적용), 파일은 Cloudflare R2

맞는 용도: 내 기기들 사이에서 텍스트나 파일 옮기기, 눈앞의 상대에게 코드를 불러 주기, Pod·서버의 산출물을 원격 사용자에게 전달하기, 고객에게 단기 유효한 다운로드 링크 주기.

맞지 않는 용도: 회수해야 할 내용, 오래 보관해야 할 내용, 키·자격 증명·개인정보(§7 참고).

2웹에서 쓰기

2.1 만들기

pasty.youlidao.ai 를 열면 기본이 「만들기」 탭입니다.

  1. 텍스트: 입력창에 쓰거나 붙여넣습니다. 오른쪽 아래에 사용 / 50,000 가 표시되고, 넘으면 빨갛게 바뀌며 버튼이 비활성화됩니다.
  2. 파일(선택): 점선 영역에 끌어다 놓거나, 눌러서 고르거나, 텍스트 입력창에 포커스가 없을 때 ⌘V(윈도우는 Ctrl+V)로 클립보드의 이미지를 붙여넣습니다. 파일은 하나만 되며 여러 개를 놓으면 첫 개만 쓰고 그렇게 알려 줍니다. 이미지는 미리보기, 그 밖은 아이콘·이름·크기·MIME 을 보여 주고 × 로 뺍니다.
  3. 만료 시간: 드롭다운, 기본값은 1일.
  4. 「만들기」를 누릅니다. 파일이 있으면 버튼이 진행률로 바뀝니다. 텍스트가 50,000자를 넘거나 파일이 100MB 를 넘으면 요청을 보내기 전에 브라우저에서 막습니다.
  5. 결과 화면: 큼직한 공유 코드, 만료 안내, 코드 복사, 새로 만들기.

2.2 받아가기

2.3 보기 화면의 구성

오른쪽 위에 남은 시간(「4분 후 만료」「3시간 후 만료」「6일 후 만료」)이 표시됩니다. 그 아래는 내용 종류에 따라:

내용표시
텍스트고정폭 <pre> 로 그대로(줄바꿈과 들여쓰기 보존), 아래에 복사 버튼
이미지png / jpeg / gif / webp / svg 는 화면 안에서 바로 보이고, 누르면 원본이 새 탭에서 열립니다. 아래에 이름과 크기
PDF브라우저 기본 뷰어를 끼워 넣고 옆에 「새 탭에서 열기」와 「내려받기」. iOS Safari 는 끼워 넣은 틀에 첫 쪽만 보여 줍니다 — 「새 탭에서 열기」를 쓰세요
그 밖zip, Word, Excel, 영상 등: 파일 카드(아이콘·이름·크기·MIME) + 내려받기 버튼
텍스트 + 파일텍스트 먼저, 첨부 구분선, 그다음 파일

10초 안에 응답이 없으면 시간 초과를 알립니다.

2.4 남에게 넘기는 세 가지 방법

형태예쓰기 좋은 상황
코드만MN3W2R말로, 손으로, 전화로. 상대가 첫 화면에서 입력합니다
페이지 링크https://pasty.youlidao.ai/MN3W2R메신저나 메일. 열면 전체 화면이 나옵니다
파일 직접 링크https://pasty.youlidao.ai/api/pastes/MN3W2R/file이미지와 PDF 는 바로 그려지고 나머지는 내려받아집니다. <img> 나 wget 에 넣기 좋습니다

3명령줄 / 스크립트에서 쓰기

3.1 텍스트 보내기

curl -s -X POST https://pasty.youlidao.ai/api/pastes \
  -H 'Content-Type: application/json' \
  -d '{"content":"공유할 텍스트","expiresIn":"1h"}'
# → {"code":"7FZEN4","expiresAt":"2026-09-09T16:56:23.246Z"}

내용이 파일에서 올 때는 손으로 이스케이프하지 말고 jq 로 JSON 을 만드세요:

jq -n --rawfile c notes.md '{content:$c, expiresIn:"1d"}' \
  | curl -s -X POST https://pasty.youlidao.ai/api/pastes \
      -H 'Content-Type: application/json' --data @-

3.2 파일 보내기(설명도 함께)

curl -s -m 120 -X POST https://pasty.youlidao.ai/api/pastes \
  -F "file=@/path/보고서.pdf" \
  -F "content=이게 무엇인지 한 줄로" \
  -F "expiresIn=1h"
# → {"code":"KTCK33","expiresAt":"…","hasFile":true}

3.3 가져오기

# 메타데이터 + 텍스트
curl -s https://pasty.youlidao.ai/api/pastes/KTCK33
# 텍스트만
curl -s https://pasty.youlidao.ai/api/pastes/KTCK33 | jq -r .content
# 파일 내려받기 (-J 는 서버가 준 이름, -O 는 저장)
curl -s -O -J https://pasty.youlidao.ai/api/pastes/KTCK33/file

/raw 엔드포인트는 없습니다. GET /{CODE} 가 돌려주는 것은 프런트엔드의 HTML 입니다. 스크립트에서는 항상 /api/pastes/{CODE} 를 호출해 .content 를 쓰세요.

3.4 기기 사이에 파일을 옮길 때 권장 절차

# 보내는 쪽
shasum -a 256 FILE
curl -s -X POST https://pasty.youlidao.ai/api/pastes -F "file=@FILE" -F "expiresIn=30m"
# 받는 쪽
curl -s -O -J https://pasty.youlidao.ai/api/pastes/CODE/file
shasum -a 256 FILE   # 보내는 쪽과 비교

전송 자체는 무손실입니다(zip / png 왕복에서 바이트 일치 실측). 체크섬은 코드를 잘못 적거나 내려받다 끊긴 경우를 잡기 위한 것입니다.

JSON 텍스트밖에 보낼 수 없는 환경(오래된 스크립트, 제한된 샌드박스)이라면 base64 로 우회할 수 있습니다. base64 -i FILE | tr -d '\n' 을 content 로 보내고 받는 쪽에서 base64 -d 합니다. base64 는 용량이 ×1.33 이 되고 100KB 본문 제한도 받으므로 작은 파일에만 맞습니다.

4API 레퍼런스

4.1 엔드포인트 개요

메서드경로용도속도 제한(IP 기준)
GET/api/health상태 확인없음
POST/api/pastesapplication/json = 텍스트만, multipart/form-data = 파일 ± 텍스트JSON 분당 10회, multipart 분당 5회. 카운터는 각각 독립
GET/api/pastes/:code메타데이터 + 텍스트 가져오기없음
GET/api/pastes/:code/file파일 스트리밍 내려받기 / 미리보기없음
POST/api/pagesHTML 페이지 하나 호스팅(토큰 필요): JSON html 또는 multipart file분당 10회
GET/p/:code호스팅된 페이지를 샌드박스 CSP로 표시없음
GET/p/:code/pdf호스팅된 페이지를 A4 PDF로 내보내기(첫 렌더링 후 캐시)분당 10회

생성 응답에는 항상 속도 제한 헤더가 붙습니다: ratelimit-limit, ratelimit-remaining, ratelimit-reset(초), ratelimit-policy(예 10;w=60). 초과하면 429 를 돌려주고 code 는 RATE_LIMITED(텍스트) 또는 FILE_RATE_LIMITED(파일)입니다.

4.2 POST /api/pastes · JSON

{ "content": "필수. 앞뒤 공백을 뺀 뒤 비어 있지 않고 50,000자 이하",
  "expiresIn": "5m | 30m | 1h | 1d | 7d (생략 가능, 기본 1d)" }
// 201
{ "code": "7FZEN4", "expiresAt": "2026-09-09T16:56:23.246Z" }

요청 본문 상한은 100KB. Express 의 JSON 파서 제한이라 글자 수 검사보다 먼저 걸립니다. 한중일 문자 40,000자는 약 120KB 라서 413 request entity too large 가 납니다. 긴 글은 약 33,000자 안으로 줄이거나, 이 제한이 없고 50,000자를 다 쓸 수 있는 multipart 의 content 필드로 바꾸세요.

검증 실패의 형태(details 는 JSON 경로에만 붙습니다):

{ "error": "Content must not be empty",
  "code": "CONTENT_EMPTY",
  "details": [ { "path": "content", "message": "CONTENT_EMPTY" } ] }

4.3 POST /api/pastes · multipart

필드필수규칙
filecontent 와 둘 중 하나파일 하나 100MB 이하(104,857,600 바이트), 형식 제한 없음
contentfile 과 둘 중 하나앞뒤 공백을 뺀 뒤 비어 있지 않고 50,000자 이하
expiresIn아니오위와 같음, 기본 1d

201 응답은 { "code", "expiresAt", "hasFile": true } 이며 파일이 없으면 hasFile 이 없습니다. 처리 순서는 R2 가 먼저이고 성공해야 Redis 에 씁니다. R2 가 실패하면 아무것도 남지 않고, Redis 가 실패하면 R2 객체를 지워 되돌립니다.

파일 이름 규칙:

4.4 MIME 판정 — 미리보기냐 내려받기냐를 정함

서버는 클라이언트가 알려 준 Content-Type 을 그대로 믿지 않고 다음 순서로 정합니다:

  1. 파일의 매직 넘버(이미지, PDF, zip, Office, 오디오·비디오 등 이진 형식)
  2. 클라이언트의 선언. 단 비어 있지 않고 application/octet-stream 이 아닐 때만(매직 넘버가 없는 txt / csv / json / svg 를 잡습니다)
  3. 확장자
  4. application/octet-stream

그래서 curl -F file=@x.zip 은 application/zip 으로 저장되고, 확장자도 선언도 없는 PDF 도 PDF 로 알아보고 미리보기가 되며, PDF 를 .txt 로 바꿔 올려도 PDF 로 다룹니다.

4.5 GET /api/pastes/:code

코드는 정확히 6자이고 모두 집합 안의 문자여야 하며, 아니면 400 입니다. 서버에서 대문자로 맞춥니다.

{
  "content": "설명 문구(파일만 있을 때는 빈 문자열)",
  "type": "text | file | mixed",
  "fileMetadata": {
    "fileName": "스크린샷.png", "fileSize": 74, "mimeType": "image/png",
    "storageKey": "pastes/U9RBRW/스크린샷.png"
  },
  "createdAt": "2026-09-09T17:00:41.045Z",
  "expiresAt": "2026-09-09T17:05:41.045Z"
}

type 과 fileMetadata 는 파일이 있을 때만 나옵니다. 초기의 텍스트 전용 기록에는 type 자체가 없을 수 있으며 그때는 text 로 다루세요.

4.6 GET /api/pastes/:code/file

파일 본체를 스트림으로 돌려주며 메모리에 담아 두지 않습니다. 응답 헤더:

헤더값
Content-Type판정된 MIME
Content-Dispositionimage/* → inline, PDF → inline; filename=…, 그 밖 → attachment; filename=…(RFC 5987 인코딩이라 비 ASCII 이름도 안전)
Content-Length파일 크기
Content-Security-Policy인라인 응답(이미지·PDF)은 사이트 기준에 sandbox 를 더해 스크립트가 절대 실행되지 않습니다. 첨부 응답은 기준 그대로입니다

4.7 오류 코드 표

모든 오류 응답은 { "error": <영문 설명>, "code": <식별자> } 입니다. 프로그램에서는 code 로 분기하세요. 이쪽이 안정된 계약이고 error 는 사람이 읽는 영문이라 표현이 바뀔 수 있습니다. 웹 화면은 error 를 보여 주지 않고 code 로 자체 사전을 찾아 방문자의 언어로 표시합니다.

상태code발생 상황
400CONTENT_EMPTYcontent 가 비었거나 공백뿐
400INVALID_EXPIRYexpiresIn 이 5m/30m/1h/1d/7d 가 아님
400INVALID_CODE_FORMAT공유 코드가 6자의 올바른 문자가 아님
400NO_CONTENT_PROVIDEDmultipart 에 content 도 file 도 없음
400FILENAME_TOO_LONG / FILENAME_INVALID파일 이름이 255자 초과 / 경로 탈출 포함
400VALIDATION_ERRORmultipart 가 손상됨, 또는 그 밖의 분류되지 않은 검증 실패
400PP_SLUG_INVALID슬러그 형식·길이가 올바르지 않거나 예약된 경로임
401PAGE_AUTH_REQUIRED토큰 없이, 또는 잘못된 토큰으로 페이지를 만들려 함
401PP_AUTH_REQUIRED토큰 없이, 또는 잘못된 토큰으로 영구 페이지를 생성함
404PASTE_NOT_FOUND코드가 없거나 만료됨
404NO_FILE_IN_PASTE그 코드는 텍스트뿐이고 파일이 없음
404FILE_NOT_FOUNDR2 객체가 이미 정리됨
413CONTENT_TOO_LARGE텍스트가 50,000자 초과, 또는 JSON 본문이 100KB 초과
413FILE_TOO_LARGE파일이 100MB 초과
413PAGE_TOO_LARGEHTML이 5MB 초과
409PP_SLUG_TAKEN이미 다른 영구 페이지나 사용 중인 공유 코드가 그 슬러그를 쓰고 있음
429RATE_LIMITED / FILE_RATE_LIMITED텍스트 생성 / 파일 업로드 제한. 카운터는 각각 독립
501FILE_UPLOAD_DISABLEDR2 가 설정되지 않은 서버에 파일이 도착함
501PAGE_HOSTING_DISABLED서버에 PAGE_API_TOKENS가 설정되지 않아 페이지 호스팅이 꺼져 있음
501PP_HOSTING_DISABLED서버에 PP_API_TOKENS가 설정되지 않아 영구 페이지 기능이 꺼져 있음
503SERVICE_UNAVAILABLE / SERVICE_BUSYRedis 장애 / 공유 코드 충돌이 5회 연속
503STORAGE_UNAVAILABLE / FILE_UPLOAD_FAILEDR2 사용 불가 / 업로드 실패
503PDF_EXPORT_UNAVAILABLEPDF 렌더링 실패, 대기열 가득 참, 또는 서버에 Chromium이 설정되지 않음
500INTERNAL처리되지 않은 서버 예외

5Claude Code / cc-hub 연동

youlidao.ai 의 cc-hub 세션과 빌드 센터 Pod 에는 pasty-share skill(v3)이 들어 있습니다. 「이거 나한테 보내 줘」「이 파일 고객에게」라고 AI 에게 말하면:

  1. multipart 로 원본 파일 그대로 올립니다. skill 의 철칙으로, PDF 나 Word 를 markdown 으로 바꿔 보내는 것은 금지되어 있습니다
  2. 기본값은 expiresIn=1h. 파일이 여럿이면 먼저 zip 으로 묶습니다
  3. 공유 코드와 보기 링크를 답하고, 이미지와 PDF 에는 /file 직접 링크도 덧붙입니다
  4. 매번 만료 시간과 「코드를 가진 사람은 누구나 볼 수 있음」을 분명히 말합니다

skill 의 금지선: .env, 개인 키, 토큰, 자격 증명, 데이터베이스 덤프는 올리지 않습니다. 민감할 수 있으면 먼저 사용자에게 묻고, 그래도 올린다면 5m / 30m 을 씁니다.

6데이터 수명 주기

단계일어나는 일
생성Redis 에 paste:{CODE} 를 선택한 만료 시간의 TTL 로 씁니다. 파일이 있으면 먼저 R2 에 pastes/{CODE}/{이름}
유효 기간 중횟수 제한 없이 읽을 수 있고 세지도 않습니다
만료Redis 키가 스스로 사라지고 조회는 404 가 됩니다
만료 후 정리서버가 한 시간마다 훑어 사라진 기록에 해당하는 R2 객체를 지웁니다. R2 자체의 수명 주기 규칙이 보조로 동작합니다(문서상 8일)
로그구조화 로그에는 IP, 크기, MIME, 정리된 파일 이름만 남기고 본문은 기록하지 않습니다

공유 코드는 CSPRNG 에 거부 샘플링을 적용해 고르게 생성합니다. 31의 6제곱 = 887,503,681가지이며, 충돌하면 최대 5회까지 다시 뽑습니다.

7보안 경계 — 쓰기 전에 반드시 읽을 것

8자주 묻는 질문

브라우저에 ERR_CONNECTION_CLOSED 가 뜨거나 curl 이 000 을 돌려줍니다
중국 본토에서 직접 연결할 때 이따금 생깁니다. 새로 고치거나 한 번 다시 시도하면 됩니다. 상태 확인과 읽기 엔드포인트 자체는 안정적입니다.
만들기 버튼이 계속 회색입니다
텍스트가 비었고 파일도 고르지 않았거나, 텍스트가 50,000자를 넘었습니다(카운터가 빨개집니다).
휴대폰에서 PDF 의 첫 쪽만 보입니다
iOS Safari 끼워 넣기 틀의 제약입니다. 「새 탭에서 열기」를 쓰세요.
한글 파일 이름이 깨져서 내려받아집니다
2026-09-10 이전에 올린 기록만 그렇습니다(그때는 서버가 이름을 latin1 로 해석했습니다). 이후 올린 것은 고쳐졌고, 오래된 기록은 만료로 사라집니다.
curl 로 올린 zip 이 예전에는 application/octet-stream 이었습니다
curl 이 .zip 을 몰라서 octet-stream 이라고 선언했고 예전 코드가 그대로 믿었습니다. 이제는 파일 내용으로 판정하므로 ;type= 이 필요 없습니다.
내용을 고치거나 지우거나 기한을 늘릴 수 있나요
없습니다. 그런 엔드포인트가 없으니 새로 만드세요.
429 가 나오면 어떻게 하나요
응답 헤더의 ratelimit-reset(초)만큼 기다리세요. 텍스트는 분당 10회, 파일은 분당 5회이고 IP 기준입니다. 파일이 여럿이면 zip 하나로 묶으세요.
긴 글이 413 request entity too large 로 안 보내집니다
JSON 본문 상한이 100KB 입니다. multipart 의 content 필드를 쓰거나 나눠 보내세요.
화면 언어를 바꿀 수 있나요
있습니다. 바닥글에 언어 선택(简体中文 / English / 日本語 / 한국어)이 있고 선택은 기기에 저장됩니다. ?lang=ko 처럼 직접 지정할 수도 있습니다.

9HTML 페이지 호스팅: AI 에이전트용 임시 웹 페이지

9.1 무엇을 위한 기능인가

AI 에이전트가 보고서, 대시보드, 프로토타입을 만들었을 때 사람에게 건네야 하는 것은 내려받을 파일이 아니라 열면 바로 보이는 URL입니다. HTML 문서 하나를 POST하면 https://pasty.youlidao.ai/p/{CODE}를 돌려받고, 만료되면 자동으로 삭제됩니다.

항목내용
만들 수 있는 사람토큰 보유자: 헤더 Authorization: Bearer <token>. 서버에 토큰이 설정되어 있지 않으면 501을 반환하며 기능이 꺼져 있습니다
볼 수 있는 사람다른 콘텐츠와 마찬가지로 코드나 링크가 있으면 누구나. 로그인 불필요
크기HTML 문서 하나당 5 MB 이하
만료5m / 30m / 1h / 1d / 7d, 기본값 1일
공유 코드텍스트·파일과 같은 코드 공간을 씁니다. /{CODE}는 페이지 카드를, /p/{CODE}는 페이지 자체를 보여 줍니다
요청 제한IP당 분당 10회

9.2 페이지 만들기

curl -s -X POST https://pasty.youlidao.ai/api/pages \
  -H "Authorization: Bearer $PASTY_PAGE_TOKEN" \
  -F "file=@report.html" \
  -F "expiresIn=7d"
# → {"code":"MN3W2R","expiresAt":"…","url":"https://pasty.youlidao.ai/p/MN3W2R"}

HTML이 이미 변수에 있다면 JSON으로 보냅니다. 필드 이름은 html입니다:

jq -n --rawfile h report.html '{html:$h, expiresIn:"1d"}' \
  | curl -s -X POST https://pasty.youlidao.ai/api/pages \
      -H "Authorization: Bearer $PASTY_PAGE_TOKEN" \
      -H 'Content-Type: application/json' --data @-

9.3 페이지를 열었을 때 할 수 있는 것

/p/{CODE}는 text/html; charset=utf-8로, 전용 CSP와 함께 반환됩니다:

가능불가능
인라인 스크립트, 그리고 다음 CDN의 스크립트: cdnjs.cloudflare.com, cdn.jsdelivr.net, unpkg.com, cdn.tailwindcss.com네트워크 호출: fetch / XHR / WebSocket 모두 차단(connect-src 'none')
인라인 스타일, Google Fonts, data: 글꼴양식 제출(form-action 'none')
https / data: / blob: 출처의 이미지·오디오·동영상iframe, object 삽입
팝업, 외부 링크를 새 탭에서 열기localStorage / 쿠키: 페이지는 독립된 샌드박스(별도 출처)에서 실행되므로 접근하면 예외가 발생합니다

샌드박스 덕분에 페이지의 스크립트는 pasty 자체로 행세할 수 없고, 이 사이트에 저장된 어떤 것도 읽을 수 없습니다. 외부 전송 차단은 페이지가 피싱 양식으로 쓰이지 않게 하기 위한 것이지만 완벽하지는 않습니다(이미지 URL이나 페이지 이동으로 데이터를 내보낼 수 있음). 진짜 관문은 만들 때 필요한 토큰입니다.

코드가 없거나, 만료되었거나, 페이지가 아니라 텍스트·파일이면 /{CODE}로 302 리디렉션되어 일반 보기 페이지에서 상황을 안내합니다. 익명 파일 업로드로 올라온 .html은 항상 다운로드로만 제공되며 /p/에서 표시되지 않습니다.

9.4 페이지를 작성하는 AI용 체크리스트

  1. 파일 하나로 완결: CSS와 JS는 인라인, 이미지는 data: URI 또는 https 링크, 라이브러리는 cdnjs.cloudflare.com, cdn.jsdelivr.net, unpkg.com, cdn.tailwindcss.com에서 버전을 고정해 불러옵니다.
  2. 네트워크 요청에 의존하지 않기: JSON을 fetch하지 말고 데이터를 페이지에 직접 넣습니다.
  3. localStorage 쓰지 않기. 꼭 써야 한다면 try/catch로 감싸고, 없어도 페이지가 보이게 합니다.
  4. <meta charset="utf-8">와 viewport를 넣어 휴대폰에서도 읽히게 합니다. 중국 본토에서는 Google Fonts가 불안정하므로 모든 글꼴에 시스템 글꼴 대체를 지정합니다.
  5. 만료는 기본 1d, 사람에게 보여 줄 보고서라면 7d. 답장에는 url과 만료 시각을 쓰고, 링크가 있으면 누구나 볼 수 있다고 알립니다.
  6. 비밀 키, 개인정보, 내부 자격 증명은 넣지 않습니다. 규칙은 §7과 같습니다.

기계가 읽을 전체 설명은 /llms.txt에 있습니다.

9.5 PDF로 내보내기

호스팅된 페이지마다 오른쪽 아래에 Export PDF 버튼이 있습니다(브라우저 언어가 중국어인 독자에게는 중국어로 표시). 링크는 /p/{CODE}/pdf이며, 이 주소를 그대로 공유해도 됩니다.