Pasty 使い方

チームで自前運用している軽量な受け渡し板。テキストかファイルを置くと 6 文字の共有コードが出て、コードだけで受け取れ、期限が来ると自動削除されます。

サイト pasty.youlidao.ai 2026-10-16 にソースと照合
MN3W2R
共有コードは 6 文字、31 文字の集合から:23456789ABCDEFGHJKMNPQRSTUVWXYZ。見間違えやすい 0/O/1/I/L は除いてあるので口頭で伝えても間違いません。入力時の大文字小文字は問いません。

1これは何か

項目事実
HTML ページAI エージェント向け:トークンを使って HTML ページを 1 つホストし、ブラウザでそのまま開ける /p/ の URL を得る(§9 参照)
ログイン不要。作成も閲覧も認証なし、コードを持っていれば読めます
内容テキスト / ファイル1つ / テキスト+ファイル
テキスト上限50,000 文字(JSON エンドポイントは別途リクエスト本体 100KB の制限あり・§4.2)
ファイル上限100 MB、1ファイル、形式は自由
有効期限5分 / 30分 / 1時間 / 1日 / 7日。既定は 1日
削除 / 編集 / 一覧いずれもありません。作成後は取り消せず、期限を待つだけです
保存先メタデータとテキストは Redis(TTL 付き)、ファイルは Cloudflare R2

向いている用途:自分の端末間でテキストやファイルを移す、目の前の相手にコードを口頭で伝える、Pod やサーバー上の成果物を遠隔の相手に渡す、顧客に短期間だけ有効なダウンロードリンクを渡す。

向かない用途:取り消しが必要なもの、長期保存が必要なもの、鍵・認証情報・個人情報(§7 参照)。

2ウェブでの使い方

2.1 作成する

pasty.youlidao.ai を開くと、既定で「作成」タブです。

  1. テキスト:入力欄に入力または貼り付け。右下に 使用中 / 50,000 が出て、超えると赤くなりボタンが無効になります。
  2. ファイル(任意):破線の領域にドロップ、クリックして選択、またはテキスト欄にフォーカスがない状態で ⌘V(Windows は Ctrl+V)でクリップボードの画像を貼り付け。ファイルは1つだけで、複数落とすと最初の1つだけを取り、その旨を表示します。画像はサムネイル、それ以外はアイコン・名前・サイズ・MIME を表示し、× で外せます。
  3. 有効期限:ドロップダウン、既定は「1日」。
  4. 「作成する」を押します。ファイルがある場合はボタンが進捗表示になります。テキストが 50,000 文字超、ファイルが 100MB 超の場合はブラウザ側で送信前に弾きます。
  5. 結果画面:大きな共有コード、期限、コードのコピー、続けて作成。

2.2 受け取る

2.3 閲覧ページの見え方

右上に残り時間(「残り 4 分」「残り 3 時間」「残り 6 日」)が出ます。その下は内容の種類ごとに:

内容表示
テキスト等幅の <pre> でそのまま表示(改行とインデントを保持)、下にコピーボタン
画像png / jpeg / gif / webp / svg はページ内に表示。クリックで原寸を新しいタブで開きます。下にファイル名とサイズ
PDFブラウザ内蔵ビューアを埋め込み、隣に「新しいタブで開く」と「ダウンロード」。iOS Safari では埋め込み枠に最初の1ページしか出ません——「新しいタブで開く」を使ってください
その他zip、Word、Excel、動画など:ファイルカード(アイコン・名前・サイズ・MIME)+ダウンロードボタン
テキスト+ファイル先にテキスト、添付の区切り線、その下にファイル

10 秒応答がない場合はタイムアウトを通知します。

2.4 相手への渡し方3種

形例向く場面
コードだけ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 ページを 1 つホスト(トークン必須):JSON の html または multipart の file1 分あたり 10 回
GET/p/:codeホストされたページをサンドボックス CSP 付きで表示なし
GET/p/:code/pdfホストされたページを A4 の PDF に書き出す(初回描画後はキャッシュ)1 分あたり 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 文字以内に収めるか、multipart の content フィールド(この制限がなく 50,000 文字まで使えます)に切り替えてください。

検証失敗時の形(details は JSON 経路にのみ付きます):

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

4.3 POST /api/pastes · multipart

フィールド必須規則
filecontent とどちらか1ファイル 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 になります
期限後の整理サーバーが1時間ごとに走査し、消えた記録に対応する R2 オブジェクトを削除します。R2 側のライフサイクル規則も保険として働きます(文書上は8日)
ログ構造化ログに残るのは IP、サイズ、MIME、無害化後のファイル名だけで、本文は記録しません

共有コードは CSPRNG に棄却サンプリングを掛けて一様に生成します。31 の 6 乗 = 887,503,681 通りで、衝突時は最大 5 回まで引き直します。

7安全上の境界(使う前に必読)

8よくある質問

ブラウザで ERR_CONNECTION_CLOSED、または curl が 000 を返す
中国本土からの直接接続で時々起きます。再読み込みか一度の再試行で通ります。ヘルスチェックと読み取りのエンドポイント自体は安定しています。
作成ボタンが灰色のまま
テキストが空でファイルも選んでいないか、テキストが 50,000 文字を超えています(カウンタが赤くなります)。
スマホで PDF の1ページ目しか見えない
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=ja のように直接指定することもできます。

9HTML ページのホスティング:AI エージェント向けの一時的な Web ページ

9.1 何のための機能か

AI エージェントがレポート、ダッシュボード、プロトタイプを作ったとき、相手に渡したいのはダウンロードするファイルではなく開けばすぐ見られる URL です。HTML ドキュメントを 1 つ POST すると https://pasty.youlidao.ai/p/{CODE} が返り、期限が来ると自動で消えます。

項目内容
作成できる人トークンを持つ人:ヘッダー Authorization: Bearer <token>。サーバーにトークンが設定されていない場合は 501 を返し、機能はオフです
閲覧できる人他のコンテンツと同じく、コードやリンクを知っていれば誰でも。ログイン不要
サイズHTML ドキュメント 1 つあたり 5 MB まで
有効期限5m / 30m / 1h / 1d / 7d、既定は 1 日
共有コードテキストやファイルと同じコード空間。/{CODE} はページのカードを表示し、/p/{CODE} はページを表示します
レート制限IP ごとに 1 分あたり 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 / Cookie:ページは独立したサンドボックス(別オリジン)で動くため、アクセスすると例外になります

サンドボックスにより、ページのスクリプトは pasty 本体になりすますことも、このサイトの保存データを読むこともできません。外部送信の禁止は、ページをフィッシングフォームとして使わせないためのものですが、完全ではありません(画像 URL やページ遷移でデータを持ち出せます)。本当の関門は作成時のトークンです。

コードが存在しない、期限切れ、またはページではなくテキストやファイルの場合は /{CODE} へ 302 でリダイレクトし、通常の閲覧ページで状況を表示します。匿名のファイルアップロードで送られた .html は常にダウンロード扱いで、/p/ で表示されることはありません。

9.4 ページを書く AI 向けチェックリスト

  1. 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 で、このアドレスをそのまま共有することもできます。