開発者ドキュメント / REST API
自動化の仕事を、ひとつの会話へ。
メッセージの送信から返信、承認された業務の結果まで。Pushyou REST APIでつなぎましょう。
自分の接続を設定01はじめる前に
招待されたPushyou内部テストアプリでアカウントと会話を作成してください。WebログインにはアプリでのQR承認が必要です。接続設定で会話を選び、実際の配信を確認できます。
設定 → 接続管理でプログラムごとの接続を作成し、必要な会話と操作のみを許可してください。キーは発行時に一度だけ表示されます。選択した会話への権限では新しい会話を作成できません。すべての会話へのアクセスとconversations:writeが必要です。
02認証
コンピューターまたはサーバーのBashかzshで実行します。キーは実行環境のシークレット設定に保存し、ブラウザーのコード、URL、公開する会話画面に含めないでください。MCP OAuthトークンはREST認証には使えません。
export PUSHYOU_API_URL='https://asia-northeast3-pushyou-prod.cloudfunctions.net/pushyouApi'
export PUSHYOU_MEDIA_URL='https://asia-northeast3-pushyou-prod.cloudfunctions.net/pushyouMedia'printf 'Pushyou API key: ' >&2
IFS= read -r -s PUSHYOU_API_KEY
printf '\n' >&2
export PUSHYOU_API_KEYcurl --fail-with-body --silent --show-error \
-X GET "$PUSHYOU_API_URL/v1/me" \
-H "Authorization: Bearer $PUSHYOU_API_KEY"03最初のメッセージを送信
既存の会話を選択
アカウント応答のid、permissions、conversation_idsを確認します。conversation_idsがnullなら全会話へのアクセスです。許可された会話を取得し、YOUR_CONVERSATION_IDを実際のIDに置き換えてください。一覧取得にはconversations:readが必要です。
curl --fail-with-body --silent --show-error \
-X GET "$PUSHYOU_API_URL/v1/conversations?limit=20" \
-H "Authorization: Bearer $PUSHYOU_API_KEY"export PUSHYOU_CONVERSATION_ID='YOUR_CONVERSATION_ID'curl --fail-with-body --silent --show-error \
-X POST "$PUSHYOU_API_URL/v1/conversations/$PUSHYOU_CONVERSATION_ID/messages" \
-H "Authorization: Bearer $PUSHYOU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"id":"docs-message-01","text":"Pushyou connection verified.","notify":true}'{
"conversation_id": "YOUR_CONVERSATION_ID",
"message_id": "docs-message-01",
"duplicate": false
}同じメッセージには同じIDを使います。同じIDと内容で再送するとHTTP 200とduplicate: trueが返ります。同じIDで異なる内容は409です。新しいメッセージには新しいIDを使ってください。
メッセージのフィールド
| フィールド | 仕様 |
|---|---|
id | 必須。英数字、アンダースコア、ハイフンで1〜80文字。 |
text | 最大8,000文字。空でないテキストまたは添付ファイルが必要です。 |
attachment_ids | 同じ会話にアップロード済みのファイルIDを最大4件指定します。 |
card | 任意。report、actions、htmlカード。カードだけではテキストや添付の代わりになりません。 |
notify | 真偽値、初期値true。プッシュ通知を要求します。実際の配信には端末の許可と通知設定も影響します。 |
会話、メッセージ、履歴の一覧はlimit(1〜100、初期値50)とbefore=next_cursorを使います。フィルターを維持し、next_cursorがnullなら終了します。イベントは数値のafterカーソルで昇順に取得します。APIでの取得はアプリの既読処理とは別です。
04返信と業務の実行
アプリで返信してからイベントを取得します。通常の返信や操作を実際に処理した後、結果の保存、ACK、next_cursorの永続保存の順に進めます。ACKはイベント削除や排他的な実行権ではありません。通常の自動応答は会話ごとに1つのプログラムにするか、独自に調整してください。
curl --fail-with-body --silent --show-error \
-X GET "$PUSHYOU_API_URL/v1/conversations/$PUSHYOU_CONVERSATION_ID/events?after=0" \
-H "Authorization: Bearer $PUSHYOU_API_KEY"curl --fail-with-body --silent --show-error \
-X POST "$PUSHYOU_API_URL/v1/conversations/$PUSHYOU_CONVERSATION_ID/events/YOUR_EVENT_ID/ack" \
-H "Authorization: Bearer $PUSHYOU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{}'承認を依頼
curl --fail-with-body --silent --show-error \
-X POST "$PUSHYOU_API_URL/v1/conversations/$PUSHYOU_CONVERSATION_ID/tasks" \
-H "Authorization: Bearer $PUSHYOU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"id":"docs-report-01","title":"Review the weekly report","category_id":"reports","fields":[{"id":"notes","label":"Review notes","type":"multiline","required":false}]}'タスクは承認と実行結果をまとめて追跡します。所有者の承認後、ワーカーはtask_protocol=1でイベントを取得し、実行トークンを永続保存してから試行を取得します。heartbeatで権利を維持し、実際の結果を保存してcompleteを送ります。完了時にイベントもACKされます。単独のACKでは未完了タスクを終了できません。
タスクのフィールド・実行権・結果仕様(英語) ↗Response receiver
継続的な返信にはRESTプログラムキーでNode 22以降のレシーバーを実行します。送信とACKの前に結果を保存します。プロセスの継続実行が必要で、PCのスリープ中は動きません。Codexモードは専用セッションを開始し、既存のチャットには接続しません。
Webhooks
署名付きの応答Webhookも利用できます。モバイルアプリの応答Webhook設定で接続してください。元の本文の署名を検証し、配信IDで重複を除きます。HTTP 2xxは受信確認であり、タスク完了ではありません。署名と再試行の仕様は業務ガイドにあります。
05ファイルと会話の画面
ファイルは専用のメディアエンドポイントと、media:writeまたはmedia:read権限のRESTキーを使います。元のバイト列をアップロードし、同じ会話のメッセージにファイルIDを添付します。ファイルURLは非公開で認証が必要です。画像は10 MiB、動画は25 MiBまでです。
curl --fail-with-body --silent --show-error \
"$PUSHYOU_MEDIA_URL/v1/media/docs-image-01?conversation_id=$PUSHYOU_CONVERSATION_ID" \
-H "Authorization: Bearer $PUSHYOU_API_KEY" \
-H 'Content-Type: application/octet-stream' \
-H 'X-Pushyou-Filename: review.png' \
--data-binary @review.pngcurl --fail-with-body --silent --show-error \
-X POST "$PUSHYOU_API_URL/v1/conversations/$PUSHYOU_CONVERSATION_ID/messages" \
-H "Authorization: Bearer $PUSHYOU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"id":"docs-attachment-01","text":"Please review this image.","attachment_ids":["docs-image-01"]}'MCPではpushyou_prepare_media_uploadにmedia_id、filename、content_type、バイト数、SHA-256を渡します。返されたupload.urlと専用ヘッダーをそのまま使い、5分以内に元のバイト列をPOSTしてからattachment_idsを送信します。RESTにも同じ準備APIがあります。アップロード権限をアカウントキーやMCP OAuthトークンに置き換えないでください。
PATCH …/viewに{"view": CARD}を送り、レポート、操作ボタン、HTML画面を公開できます。{"view": null}で削除します。画面は所有する会話から開きます。HTMLは外部通信、アプリの認証情報、ブラウザーの保存領域にアクセスできません。宣言した操作は同じ会話のイベントになります。
Card / Field
Card =
{ type: "report", title: string, items: { title: string, body?: string, label?: string }[] }
| { type: "actions", title: string, body?: string, actions: { id: ID, label: string }[] }
| { type: "html", title: string, html: string, height?: integer, actions?: { id: ID, label: string }[] }
Field = { id: ID, label: string, type: "text" | "multiline" | "number" | "date" | "select" | "checkbox", required?: boolean, options?: string[], min?: number, max?: number }06エンドポイント一覧
各グループのベースURLにパスを追加します。ファイル専用のアップロード権限を使う場合以外はBearerプログラムキーが必要です。項目を開いてリクエスト形式を確認し、例のIDを置き換えてください。
JSON API
https://asia-northeast3-pushyou-prod.cloudfunctions.net/pushyouApiPOST/v1/conversations/{id}/media/uploads
ファイルのアップロードを準備
ファイルID・名前・形式・バイト数・SHA-256を指定すると、5分間有効なファイル専用の送信権限を取得できます。media:writeが必要です。
{ media_id: ID, filename: string, content_type: string, size: integer, sha256: string }GET/v1/me
アカウントを確認
このAPIキーに紐づくアカウントと権限を確認します。
GET /v1/me
→ { id, key_scope, permissions, conversation_ids }POST/v1/conversations
会話を作成
idとnameで会話を作成します。同じID・内容で再試行しても重複作成されません。
{ id: ID, name: string, description?: string, kind?: string, view?: Card }GET/v1/conversations
会話の一覧
アカウントの会話一覧を取得します。
?limit=20&before=CURSOR
→ { conversations, next_cursor }GET/v1/conversations/{id}
会話を取得
会話の名前・説明・状態・公開ビューを取得します。
GET /v1/conversations/ROOM_ID
→ { conversation }PATCH/v1/conversations/{id}
会話を更新
名前・説明・固定状態を更新します。activeで会話を一時停止・再開できます。
{ name?: string, description?: string, pinned?: boolean, active?: boolean, view?: Card | null }POST/v1/conversations/{id}/messages
メッセージを送信
テキスト・カード・添付を送信します。送信済みファイルのIDをattachment_idsに指定し、notifyで通知を制御します。
{ id: ID, text?: string, attachment_ids?: ID[], card?: Card | null, notify?: boolean }GET/v1/conversations/{id}/messages
会話を読む
受信メッセージとユーザーの返信を新しい順に取得します。
?limit=20&before=CURSOR
→ { messages, next_cursor }GET/v1/conversations/{id}/messages/{message_id}
メッセージを取得
メッセージ1件の内容とカードを読みます。
GET /v1/conversations/ROOM_ID/messages/MESSAGE_ID
→ { message }GET/v1/conversations/{id}/events/head
現在の応答番号
新しい受信プログラムを始める前に最新の番号を取得します。既読や処理済みの状態は変えません。
GET /v1/conversations/ROOM_ID/events/head
→ { cursor }GET/v1/conversations/{id}/receiver-status
受信プログラムの状態を取得
最後に報告された受信状態と時刻を確認します。タスクの完了や実行権の取得を確認するものではありません。
GET /v1/conversations/ROOM_ID/receiver-status
→ { receivers, checked_at }PUT/v1/conversations/{id}/receiver-status/{instance_id}
受信プログラムの状態を報告
実行ごとに新しいUUIDと増加するsequenceで報告します。会話の読み取り・イベントの読み取り・ACK・メッセージの書き込み権限が必要です。
{ sequence: positive_integer, state: "starting" | "receiving" | "processing" | "retrying" | "paused" | "stopped" | "needs_review" | "delivery_pending" }
instance_id: UUID v4GET/v1/conversations/{id}/events
ユーザーの応答を取得
指定した番号以降の返信と送信済みボタン操作を取得します。
?after=0
?after=0&task_protocol=1
→ { events, next_cursor }POST/v1/conversations/{id}/events/{event_id}/ack
応答の処理を確認
エージェントやサーバーが処理したイベントを処理済みにします。
{}
→ { ok: true }GET/v1/conversations/{id}/view
会話ビューを取得
会話に公開されたHTML・コンポーネントビューを読みます。
GET /v1/conversations/ROOM_ID/view
→ { view: Card | null }PATCH/v1/conversations/{id}/view
会話ビューを公開
viewにカードを送ると、会話の上部にビューを開く操作が追加されます。nullで削除します。
{ view: Card | null }GET/v1/history
履歴を取得
category_id・kind・status_group・conversation_idを組み合わせて履歴をページ単位で取得します。
?limit=20&before=CURSOR
&category_id=reports&conversation_id=ROOM_ID
&kind=received&status_group=attention
&result_pending=true
kind: received | action | saved
status_group: attention | progress | problems | complete
→ { history, next_cursor }POST/v1/conversations/{id}/tasks
タスクの承認を依頼
安定したタスクID・タイトル・本文・フォームを送信します。ユーザーの承認後にのみ実行イベントが作成されます。
{ id: ID, title: string, body?: string, category_id?: ID, fields?: Field[], inputs?: object, expires_at?: integer, result_requires_review?: boolean }GET/v1/conversations/{id}/tasks/{task_id}
タスクの状態を取得
現在の状態・試行・入力・結果を確認します。
GET /v1/conversations/ROOM_ID/tasks/TASK_ID
→ { task }GET/v1/conversations/{id}/tasks/{task_id}/versions
依頼のバージョンを読む
同じ依頼の以前のバージョンを確認します。
GET /v1/conversations/ROOM_ID/tasks/TASK_ID/versions
→ { versions: [{revision, title, body, fields, inputs, created_at, change_request}] }POST/v1/conversations/{id}/tasks/{task_id}/revise
依頼の修正版を送る
所有者が承認できるよう修正した依頼を送ります。
{ request_id: ID, expected_revision: integer, change_request_id?: ID, body: string, title?: string, fields?: Field[], inputs?: object }
Only pending or changes_requested tasks can be revised. Approval is required for every new version.POST/v1/conversations/{id}/tasks/{task_id}/claim
タスクの実行権を取得
実行トークンを保存してから試行の実行権を取得します。取得成功後にのみ外部処理を始めてください。
{ request_id: ID, attempt: integer, execution_token: string }POST/v1/conversations/{id}/tasks/{task_id}/heartbeat
実行権を維持
現在の実行権の10分間の期限を更新します。失効した場合、タスクは要確認になります。
{ request_id: ID, attempt: integer, execution_token: string }POST/v1/conversations/{id}/tasks/{task_id}/complete
タスクの結果を報告
結果をローカルに保存してからsucceeded・failed・needs_reviewを報告します。対応するイベントも処理済みになります。
{ request_id: ID, attempt: integer, execution_token: string, status: "succeeded" | "failed" | "needs_review", result: string, result_links?: [{label: string, url: HTTPS_URL}] }GET/v1/conversations/{id}/actions
会話のアクション一覧
会話のフォームと現在のリビジョンを読みます。
GET /v1/conversations/ROOM_ID/actions
→ { actions }PUT/v1/conversations/{id}/actions/{action_id}
会話のアクションを公開
フォームを作成・更新します。更新にはexpected_revisionが必要です。送信はユーザーが明示的に行います。
{ title: string, description?: string, fields: Field[], category_id?: ID, active?: boolean, expected_revision?: ID }メディアAPI
https://asia-northeast3-pushyou-prod.cloudfunctions.net/pushyouMediaPOST/v1/uploads/{id}
準備したファイルを送信
MCPのアップロード準備で取得したURLとファイル専用の認証ヘッダーで原本バイトを送信します。アカウントキーやMCP OAuthトークンで代用しないでください。
POST upload.url
Headers: upload.headers
Body: original file bytesPOST/v1/media/{id}?conversation_id={room}
写真・動画をアップロード
ファイルの原本バイトとURIエンコードしたX-Pushyou-Filenameヘッダーを送ります。同じIDとファイルで再試行してください。
Content-Type: application/octet-stream
X-Pushyou-Filename: URI_ENCODED_FILENAME
Body: original file bytesGET/v1/media/{id}
ファイルを取得
認証ヘッダーで写真や動画を取得します。動画は単一のRangeリクエストに対応します。
Range: bytes=0-65535 (optional)
→ original file bytesHEAD/v1/media/{id}
ファイル情報
本文をダウンロードせずにMIME形式・サイズ・Range応答ヘッダーを確認します。
HEAD /v1/media/MEDIA_ID
→ Content-Type, Content-Length, Accept-RangesDELETE/v1/media/{id}
未使用のアップロードを削除
まだメッセージに添付していないファイルを削除します。削除済みIDは再利用できません。
DELETE /v1/media/UNATTACHED_MEDIA_ID07トラブルシューティング
RESTエラーは2xx以外のステータスと{"error": "…"}を返します。MCPのツールエラーはクライアントに表示されます。構造化されたエラーと接続権限を確認してください。
400 | ID、必須フィールド、型、カーソル、リクエストサイズを確認してください。 |
|---|---|
401 | 再認証するか、キーの期限切れ、再発行、失効を確認してください。 |
403 | 操作権限、許可された会話、会話の一時停止状態を確認してください。 |
404 | リソースIDとベースURLを確認してください。/mcpはWebページではなくプロトコルのエンドポイントです。 |
409 | 異なる内容で再利用したID、古いリビジョン、タスクの実行権、添付済みのファイルなど、競合の原因を確認します。外部処理を無条件に繰り返さないでください。 |
410 | 会話を削除中、またはリソースが利用できません。現在の状態を確認してください。 |
413 | JSON本文やファイルを小さくし、アップロード上限を確認してください。 |
415 | 対応している画像・動画形式と正しいファイルを使ってください。 |
416 | 要求したバイト範囲がファイル内か確認してください。 |
429 | リクエスト制限では間隔を空けます。メディア容量不足では未使用ファイルを整理して再試行します。新規メッセージは会話ごとに毎分60件までです。 |
500 | 一時的なエラーは同じIDで間隔を空けて再試行します。外部処理が実行済みの可能性があれば、再実行前に結果を確認してください。 |