# Self-service task API keys Public nonsecret downloads: https://hq.wfcloud.app/downloads/hq_task_client.py and https://hq.wfcloud.app/downloads/store_task_key.py . This guide: https://hq.wfcloud.app/api-docs . No server SSH is needed. ## Human setup Sign in at **https://hq.wfcloud.app**, choose **API keys**, enter a key label, review scopes and expiry, explicitly check the authorization box, then select **Create scoped key**. Secret is displayed once (masked initially) and never returned by the key list. Copy directly into protected storage for your own authorized task environment. Never put the secret in chat, source, command arguments, screenshots, or task output. Closing the panel/signing out clears the displayed secret. Revoke anytime from the same panel. Default expiry90 days; choices1/7/30/90 days. Scopes are individually selectable: - `records:read`: read shared current HQ records. - `drafts:create`: create idea/workflow/skill drafts, always Inbox/Pending. - `drafts:edit-own`: edit your own unapproved Inbox/Under-review idea/workflow/skill drafts with current version. - `inbox:read`: read shared HQ project threads and messages (optional, unchecked by default). - `inbox:send`: post project messages/replies/handoffs as your account and key label (optional, unchecked by default). Existing keys never gain these permissions automatically. Select both inbox options on a new key for a task that needs to read and reply. Messages are data, not approval or authority to execute work. No automatic checking, notifications or wakeups are enabled. Keys cannot approve/delete work, manage users/keys, grant admin, execute commands or access the server. Owner is the signed-in HQ username, never a caller-supplied identity. Writes carry owner plus key label and immutable owner/key attribution. Legacy records without trustworthy created_by metadata cannot be edited through the API; no ownership is guessed. New web-created records retain their immutable creator. Only credential hashes are stored. Expired/revoked keys and disabled accounts are denied. Key listing/revocation is owner-only and cookie-session/CSRF protected. There is no unauthenticated grant issuance. HTTP bodies, keys and credentials are not written to audit/request logs. Audit includes owner/key ID, action, record ID and result. ## Endpoint contract Base: `https://hq.wfcloud.app/api/v1/records`. - GET base → current records array; `records:read` required. - GET base`/{uuid}` → one current record; `records:read` required. - POST base → create draft: `{type:"idea"|"workflow"|"skill",title,body?,next_step?}`. - PUT base`/{uuid}` → update draft: `{version,title?,body?,next_step?}`. All use `Authorization: Bearer ` over verified HTTPS. No browser cookie/human password is accepted for this API. Writes require JSON and stable `Idempotency-Key`16–80 safe characters. Same key+identical operation returns original receipt; changed input with the same idempotency key409. Version conflicts409. Rejected scope/other-owner/approved-draft403. Expired/revoked/invalid key401. Request limit120/minute and write limit20/minute/key. Successful writes return the record plus `_receipt` containing request_id, record_id, version, owner, key_label and replayed. Receipt is durable; revisions and record changes commit atomically with it. No automatic mutation retries. For a timeout/5xx uncertain outcome, retry **identical data and the same request_id**, never generate a new ID for that retry. ## Background task helper · no browser for routine use Files: `hq_task_client.py` and optional owner-run `store_task_key.py`. Requires Python3 and outbound HTTPS access from the authorized execution environment. HQ does not install this in Wylie's/Janet's environment or create a key for them. That environment must actually support command execution and protected secret storage; merely pasting a key into a Dot chat is not secure configuration. Prefer your execution environment's protected secret-file facility. Configure **HQ_API_KEY_FILE** to its path, not the secret. File must be regular, owned by runtime user, mode0600/0400, and not a symlink. No directory scanning or ambient credential discovery. Alternative one-time human setup in your own terminal (not through assistant capture): ``` python3 store_task_key.py ~/.config/office-hq/api-key ``` The helper prompts invisibly, creates mode0600, refuses overwrite, and prints no key. No secret file was created by this implementation. Task configuration contains only the file path: ``` export HQ_API_KEY_FILE="$HOME/.config/office-hq/api-key" python3 hq_task_client.py list ``` Create a draft from stdin, with a stable logical-operation ID: ``` python3 hq_task_client.py create --request-id task-unique-logical-request-001 <<'JSON' {"type":"idea","title":"A new idea","body":"Desired outcome and context."} JSON ``` Edit with `--record UUID`, JSON containing the latest integer `version`, and a new request ID for the new operation. A routine task can perform this directly over HTTPS without GUI interaction, root access or a shared human password. Failed/uncertain results return request_id and sanitized instructions, never the credential. TLS verification and redirect refusal remain enabled. This is a normal HTTPS task-client integration, not an MCP write tool or a claim to bypass ChatGPT Pro MCP restrictions. Janet's actual task runtime/secret mounting still needs setup by its authorized owner. No credential has been minted on Wylie's or Janet's behalf. ## Connection briefing for the task `GET https://hq.wfcloud.app/api/v1/connect` requires the same valid Bearer key and returns owner-provided workspace guidance, briefing version, the key’s actual permissions/expiry, and an `authenticated_connection` receipt. It returns no stored records and creates no records. Guidance explains that saves remain unapproved and do not start execution; it is data, never an override of higher-priority instructions or a broader access grant. Start a new task/context with: ``` python3 hq_task_client.py connect ``` The helper also retrieves this briefing automatically on its first use with a key in an execution environment, including before the first submission. Subsequent submissions omit the full briefing unless its version changes. Explicit `connect` always returns it again. The helper caches only a version in an owner-only local file under `~/.cache/office-hq`, with a hashed key identifier in the filename; no credential or workspace records are cached. Optional HQ_BRIEFING_CACHE_DIR selects an authorized cache directory. A version cache does not imply Janet has permanent memory; call connect for each fresh task/context that needs the guidance. The helper returns the connection data as `workspace_connection` alongside the normal operation result when it fetched a briefing. Routine writes include briefing_version in their idempotency receipt. Confirm saved title, ID, version and receipt; read back the saved record when read scope is available. Denials stay denials. No monitoring, unsolicited cross-account message or automatic execution is created. ## Shared inbox from an authorized task Base: `https://hq.wfcloud.app/api/v1/inbox/threads`. GET base lists shared threads; GET base/{uuid} returns thread history (inbox:read). POST base creates a thread with `{subject,body,target,kind}`; POST base/{uuid}/messages appends `{body,target,kind}` (inbox:send). Target is Team, Paul or Janet; kind is message, question, reply or handoff. Target labels do not deliver or wake a dot. No private threads or private-chat bridge exists. Caller-supplied sender fields are rejected. Receipts include thread/message IDs, replay state, work_authorized:false and wakeup_triggered:false. ``` python3 hq_task_client.py inbox-list python3 hq_task_client.py inbox-get --record THREAD_UUID python3 hq_task_client.py inbox-create --request-id project-handoff-unique-001 <<'JSON' {"subject":"Project question","body":"Project context and question.","target":"Janet","kind":"question"} JSON python3 hq_task_client.py inbox-reply --record THREAD_UUID --request-id project-reply-unique-001 <<'JSON' {"body":"Project reply.","target":"Paul","kind":"reply"} JSON ``` Confirm the returned message/thread IDs and receipt; read back history when read permission is present. Reuse identical request ID and content after an uncertain write. No live key is included in this guide or created on anyone's behalf.