# Tasks, automation and history Pushyou keeps requests, human decisions and results in their owning conversation. Your connected program executes the work. Primary destinations remain **Conversations, History and Settings**; conversation actions and published views open from that conversation. ## Review and track work 1. Connect a program with REST or MCP. It creates a task in an allowed conversation. 2. Open the task, review the details and form inputs, then approve or reject. Approval queues execution; it does not mean the work is complete. 3. The receiver claims the approved task, runs your handler and reports its observed result. 4. Follow the status and result in the conversation or History. Check external results before retrying a failed or uncertain task. Task states: `pending`, `queued`, `running`, `succeeded`, `failed`, `rejected`, `cancelled`, `expired`, `needs_review`. History groups them into **Needs your response**, **In progress**, **Problems & review** and **Completed**. Reminders bring an unfinished task back at the chosen time. Cancelling does not undo work already running in an external system. History has built-in categories: Uncategorized, Work, Engineering & operations, Reports & analysis, and Personal. Create, rename, reorder and archive your own categories. Archived categories remain on existing records but disappear from new assignments. Uncategorized stays available. Up to 100 categories are supported. Category, task status, record kind and conversation filters can be combined. Existing history is migrated in bounded, resumable batches without blocking sign-in. Untouched built-in names follow the selected UI language. Renamed categories, conversation names and user-authored content stay exactly as entered. Assigning a category to a task also updates its linked history entries. ## API sequence Use a program key scoped to the required conversations. Task creation requires message-write access. Execution needs message read/write and event read/ACK. A legacy conversation-only key cannot access account tasks. Browser sessions are checked for every privileged action. The API cannot approve its own task; the owner decides in the app or web. All paths below are relative to the API base shown in connection settings: | Method and path | Purpose | | --- | --- | | `POST /v1/conversations/{room}/tasks` | Create an approval request | | `GET /v1/conversations/{room}/tasks/{task}` | Read current task state | | `POST /v1/conversations/{room}/tasks/{task}/claim` | Claim an approved execution attempt | | `POST /v1/conversations/{room}/tasks/{task}/heartbeat` | Renew the execution lease | | `POST /v1/conversations/{room}/tasks/{task}/complete` | Save the result and ACK the task event | | `GET /v1/conversations/{room}/actions` | List reusable conversation actions | | `PUT /v1/conversations/{room}/actions/{action}` | Save an action definition using its expected revision | Example creation body: ```json { "id": "deploy-staging-1_0_0", "title": "Review staging deployment", "body": "Check the version and environment before approving.", "category_id": "operations", "fields": [ {"id":"version","label":"Version","type":"text","required":true}, {"id":"environment","label":"Environment","type":"select","options":["staging","production"],"required":true} ], "inputs": {"version":"1.0.0","environment":"staging"} } ``` Use a new `id` for new work. Retry the same creation request with the same ID and content. A task can include an optional start deadline. Forms support text, multiline, number, date, select and checkbox fields (up to 12 fields, 20 choices per select, 16 KB of input). Inputs are validated on the server. Conversation actions support up to 30 definitions; edits require the current `expected_revision`. 1. Read `GET …/events?task_protocol=1&after=CURSOR`. Approved execution events have `type: "task"`, `task_id`, `attempt` and approved `payload`. Default event queries remain compatible with ordinary replies/actions. 2. Generate a random 32-byte base64url `execution_token` and a `request_id`. **Persist them locally before transmission.** Claim with `{request_id,attempt,execution_token}`. 3. Start external work only after verifying the current attempt is `running` with a valid lease. Concurrent claims have one winner. If a response is lost, repeat the same request ID and token. Keep the token out of messages and logs. 4. Renew approximately every 30 seconds, using a new request ID each time. Leases last 10 minutes; an execution lasts at most 24 hours. Lease/authentication failure stops external work for review. A network retry must not rerun the external operation. 5. **Persist the final result before transmission.** Complete with `{request_id,attempt,execution_token,status,result}`. Use `succeeded`, `failed` or `needs_review`; results are limited to 8,000 characters. Completion and the task event ACK occur in one transaction. If transmission fails, resend the same stored result. 6. Save the event cursor after handling it. Separate ACK cannot complete an unfinished task. Old attempts, unrelated credentials and incorrect tokens are rejected. A recovery sweep runs about once a minute. Expired leases become `needs_review`; tasks that miss their start deadline become `expired`. Decisions and claims also check deadlines directly. Explicit retries create a new attempt/event, up to 20 attempts. Creation is limited to 60 tasks per account per minute; the latest 100 transitions are retained. Claims coordinate participating task workers, not arbitrary external programs. Use an external idempotency key too. MCP exposes the same service through `pushyou_create_task`, `pushyou_get_task`, `pushyou_claim_task`, `pushyou_heartbeat_task`, `pushyou_complete_task`, `pushyou_list_actions` and `pushyou_set_action`. Select `task_protocol:1` for `pushyou_get_events`. The catalog only exposes permitted tools. MCP does not keep an agent running. ## Response webhooks In the mobile app, open **Settings → Response webhooks**, then choose a name, public HTTPS URL, conversations and events. Supported events are `message`, `action`, `task.queued` and `task.updated`. Selected replies, inputs and results are transmitted to that destination. Up to 10 hooks per account and 1–20 conversations per hook are supported. To change the URL, create a new hook and revoke the old one. A signing key is shown once when created or rotated. The server derives it from its Secret Manager root using the account, hook and generation, without storing the raw key. Rotation stops queued deliveries from the old generation. Configure the new key before explicitly replaying a delivery. The web app supports logs and replay; connection/key management stays in the mobile app. ```text X-Pushyou-Id: stable delivery ID X-Pushyou-Timestamp: UNIX seconds X-Pushyou-Attempt: delivery attempt number X-Pushyou-Signature: v1= ``` Use the signing-key string as a **UTF-8 key**. Verify HMAC-SHA256 over `timestamp + "." + original HTTP body bytes`, before parsing JSON. Do not reserialize the body for verification. Require a timestamp within five minutes and use constant-time comparison. The body is `{id,type,created_at,conversation_id,data}`. Delivery is at least once. Deduplicate stable IDs in durable storage. A 2xx response acknowledges receipt, not work completion. Network errors, 5xx, 408 and 429 retry up to six attempts. Redirects and other 4xx are not followed or retried. Logs are retained for 30 days; the UI shows the latest 100. Explicit replay is limited to 10 times. Revocation cannot undo an in-flight network request. Destinations must be public IPv4 DNS names on HTTPS port 443. IP literals, private/loopback/reserved/metadata addresses are rejected. DNS is revalidated and pinned for each delivery; TLS validates the original hostname. IPv6-only and private-network destinations are currently unsupported. Response bodies are not stored or shown. ## Runnable examples The receiver archive and web guide include `request-task.mjs`, `workflow-handler.mjs`, `webhook-inbox.mjs` and `n8n-deploy-approval.json`. Install the archive and set the API URL/key using the receiver guide, then: ```sh receiver_examples="$(npm root -g)/@pushyou/receiver/examples" node "$receiver_examples/request-task.mjs" --template report --conversation ROOM --id project-report-2026-09-11 pushyou-receiver run --conversation ROOM --state-dir ./.pushyou-receiver/workflow --start pending -- node "$receiver_examples/workflow-handler.mjs" ``` Approve the request in Pushyou. `report` counts top-level files/folders in the receiver's working directory. `incident` inspects basic local runtime metrics. `deploy` is a **dry run** that validates version/environment input without deploying anything. Replace the handler and supply appropriate external permissions/idempotency keys for real work. Echo only verifies connectivity and never reports real task success. For the webhook inbox, configure `PUSHYOU_WEBHOOK_KEY_FILE` (private key file, mode 600), `PUSHYOU_WEBHOOK_INBOX` (directory, mode 700) and optional `PORT`. Put its loopback `/pushyou` listener behind your HTTPS proxy. It verifies signatures and persists using file fsync, atomic unique creation and directory fsync before returning 200. It does not execute tasks; use the claim/result protocol for execution. ### Import into n8n 1. Import `n8n-deploy-approval.json` using Import from File. It is an inactive manual-trigger example. 2. In **Conversation and version**, set `api_url`, `conversation_id`, `version`, `environment` and `request_id`. Preserve the request ID for the same creation retry; use a new one for new work. Retry failed execution from the Pushyou task detail. 3. Select HTTP Header Auth credentials on **Pushyou approval request**: Name `Authorization`, Value `Bearer `. Do not put raw keys in the workflow JSON or Set node. The notification-only profile is enough to create the request. 4. Run the manual trigger, then approve in Pushyou. Processing needs a receiver with the conversation-access profile and the example handler or your own program. The JSON structure and request body are tested. Verify credential configuration and execution in your n8n installation. HTTP redirects are disabled so credentials are not forwarded to another destination. ## Continuous operation and upgrades Receiver 0.4.0 generates launchd/systemd user-service files with `pushyou-receiver-service`. Keep keys separate from configuration, review the files and explicitly activate the service. The receiver installation guide contains start, stop and recovery commands. A sleeping or powered-off computer cannot run the local receiver. Upgrading a 0.3.x cursor checks missed task events once, then resumes the original cursor. It does not replay ordinary messages deliberately skipped with `--start now`. Preserve existing state and review interrupted external work first. Local folder locks do not coordinate different computers; task execution uses separate server-side claims. Account deletion removes tasks, private execution tokens, forms, categories and delivery logs. Conversation deletion removes its tasks, actions, events and delivery logs and blocks later claims/delivery. Data already sent externally, local state, n8n data and model-provider records must be managed in those systems. ## Requests, revisions and reviewed results (2026-09-12) Conversations show **Needs response** independently of unread messages. Each room has transactional pending-request and unreviewed-result counts; existing rooms initialize their counts from actual tasks. Reading a conversation does not resolve a request. History adds **Results to review**, combinable with category, room and record type. 1. Create an approval task with optional `result_requires_review:true`. Owner-submitted action forms track results by default. Ordinary incoming tasks default to false, so routine successful messages do not become mandatory review chores. 2. The owner chooses **Request changes** and writes a note. `decideTask` with `operation:request_changes`, `text`, `expected_revision` and a stable `request_id` changes `pending` to `changes_requested`. Approval is unavailable while waiting. This produces a message event carrying `task_id`, `task_intent:request_changes`, `content_revision`, and `change_request_id`. 3. A connected program returns a draft via `POST /v1/conversations/{room}/tasks/{id}/revise` (MCP `pushyou_revise_task`). Body: `{request_id,expected_revision,change_request_id,body,title?,fields?,inputs?}`. The current change request ID is required when answering a change request. Only `pending` or `changes_requested` tasks can be revised. Each accepted revision creates an immutable version and returns to `pending`; at most 50 versions. Retries use identical request IDs and content. 4. `GET .../tasks/{id}/versions` / `pushyou_get_task_versions` / owner `getTaskVersions` return versions newest first. Version snapshots contain draft fields and initial inputs. The task retains final owner-approved inputs, `approved_content_revision`, and `approved_at`. State `revision` remains separate from `content_revision`. 5. Owner approval binds the currently reviewed version and inputs. Approved/queued/running content cannot be revised. Claims and results remain bound to the same task and attempt. Receivers receive the approved request snapshot; external publishers must execute this snapshot, not an unrelated newer draft. Expired requests that were never approved return to approval on retry. 6. Completion accepts optional `result_links:[{label,url}]` (up to five HTTPS links without URL credentials). `result` remains required, max 8,000 characters. Links are references reported by the connected program, not independent verification that a remote publication exists. 7. For tracked results, `result_pending:true` stays visible until the owner calls `review_result` with the current state revision. This records `result_reviewed_at` without changing execution status or generating another message. `follow_result` with `follow:boolean` controls tracking. Query history with `result_pending=true`. Failed/uncertain execution remains a problem even after reading/reviewing its result; explicit resolve/retry rules still apply. Generic chat is still available. Native and web quoted replies preserve the source message and request context. REST/MCP `send_message` supports `reply_to` and optional `task_id`, validated inside the same conversation with read/write permission. These comments never approve a task or replace its draft. Use the explicit revision API for an updated approval request. Receiver 0.5.0 accepts `{revision:{body,title?,fields?,inputs?}}` only for a matching revision request. It persists the draft before revising/ACK, so lost responses retry delivery without rerunning the handler. It skips obsolete draft-only change events, and ambiguous or interrupted work still requires explicit review. Task results may include `result_links`. Codex mode receives the same request context and must return structured draft/result output; Pushyou does not attach to an existing desktop AI session. ### First complete connection check Use a separate test conversation and stop its echo receiver first. The desktop receiver guide provides commands tailored to that room. `request-task.mjs --template check --conversation ROOM --id STABLE_ID` sends a request. Start the bundled `workflow-handler.mjs` with the receiver. Request a change, inspect the revised text, approve, and receive the exact approved text as a result receipt. The guide marks each stage complete only from the actual task record. This deterministic example echoes the requested revision; it does not call AI, deploy, or publish content.