> ## Documentation Index
> Fetch the complete documentation index at: https://docs.typebar.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Typebar, formerly SuperDocs. Same product, same API, same keys: nothing changes for your integration.
> Typebar, formerly SuperDocs, is not related to SuperDoc (superdoc.dev).

# Agent recipe (REST)

> For agents that reach Typebar with curl: one shell command per document job. Upload a file with every instruction, get the result and the edited file back, each command under about 105 seconds.

# Typebar over REST (curl): one command per job

Each shell command costs you a model turn, so do a whole job in ONE command: every instruction in one
message, targets named by section and content. Never open, read, grep or diff the documents yourself.
Every curl has `--max-time`. Never re-send a POST that timed out (it bills a second job): re-run
only the GET wait. Never use pkill, killall or kill.

## Key (once)

Reuse `~/.superdocs/agent_credentials.json` if it exists. Otherwise sign up, which accepts the Terms
(typebar.ai/terms): only if the user's instruction says so; otherwise ask the user first.

```bash theme={null}
API=https://api.superdocs.app; umask 077; mkdir -p ~/.superdocs
[ -s ~/.superdocs/agent_credentials.json ] || curl -fsS --max-time 30 -X POST "$API/v1/agents/signup" -H 'Content-Type: application/json' -d '{"terms_accepted": true}' -o ~/.superdocs/agent_credentials.json
```

## Edit a file: one command

```bash theme={null}
API=https://api.superdocs.app; SID=tb-$(date +%s)-$$; echo "session $SID"; R=reply-$SID.json
K=$(python3 -c 'import json,sys;print(json.load(open(sys.argv[1]))["api_key"])' ~/.superdocs/agent_credentials.json)
cat > msg-$SID.txt <<'TYPEBAR_MSG_END'
EVERY INSTRUCTION, IN ONE MESSAGE
TYPEBAR_MSG_END
curl -sS --max-time 95 -X POST "$API/v1/chat/file" -H "Authorization: Bearer $K" -F "session_id=$SID" -F "wait_seconds=85" -F "approval_mode=approve_all" \
  -F "file=@\"./INPUT.docx\"" -F "message=<msg-$SID.txt" -o $R -w 'HTTP %{http_code}\n'
python3 -c 'import json,sys;r=json.load(open(sys.argv[1]));d=r.get("detail");e=r.get("edited",d.get("edited") if isinstance(d,dict) else None);print(r.get("response") or r,"[edited: false]"*(e is False));[print("HELD:",c.get("note") or c.get("operation"),"[requires_review]"*bool(c.get("requires_review"))) for c in (r.get("document_changes") or {}).get("pending_changes") or []]' $R
read U N <<< "$(python3 -c 'import json,sys;d=json.load(open(sys.argv[1])).get("download") or {};print(d.get("download_url","-"),"OUTPUT-before-this-turn.docx" if d.get("before_this_turn") else "OUTPUT.docx")' $R)"; [ "$U" != - ] && curl -sS --max-time 9 -o "./$N" "$U" -w "saved $N\n"
```

**Create** from sources: add `A=(); while IFS= read -r f; do A+=(-F "sources=@\"$f\""); done < <(find ./data ./context -type f ! -path '*/.*' 2>/dev/null)`
before the curl and replace `-F "file=@\"./INPUT.docx\""` with `"${A[@]}"`; the message is the brief. (Keep the `\"…\"`:
unquoted, curl reads `;` and `,` as options.)

## The reply

* `response`: what was done per ask. `download`: a 15-minute link (`-F export_format=pdf` for PDF).
* **HTTP 202** or a timeout: still running. Run ONE wait (again on another 202) with the printed session:
  ```bash theme={null}
  API=https://api.superdocs.app; SID=PRINTED_SESSION; R=reply-$SID-$(date +%s).json
  K=$(python3 -c 'import json,sys;print(json.load(open(sys.argv[1]))["api_key"])' ~/.superdocs/agent_credentials.json)
  curl -sS --max-time 95 "$API/v1/sessions/$SID/result?wait_seconds=85&export_format=docx" -H "Authorization: Bearer $K" -o $R -w 'HTTP %{http_code}\n'
  ```
  Then the same `python3` and `read U N` lines. The wait also re-lists held lines; guess no other endpoint.
* **`[edited: false]`** printed: nothing was edited; run the edit command again (a new session). Any
  other failure may have edited: give the user its `response` before sending again.
* **HELD lines** (`requires_approval`): nothing from this turn is applied yet; the saved
  `OUTPUT-before-this-turn.docx` predates it (a held create has none: see `download.error`).
  * `requires_review` lines need the user's own go; never approve one without it. If you can ask, ask
    BEFORE the approve call; put the ids they approve in `OK` (space-separated). If you cannot ask and
    every line is `requires_review`, stop: give the user the held lines and that one decision.
  * A note saying it could not be verified, or goes beyond the request: deny it (id in `NO`), finish, then
    re-ask that change alone: the edit command on `OUTPUT.docx`, quoting verbatim from the document (the one
    exception) the exact text to keep or the anchor. Never stop without the final file.
  * Otherwise approve in ONE call, then wait and download. Lines it does not name are declined: never
    applied, never approvable later. Until held lines are decided, a new chat answers 409.
  ```bash theme={null}
  API=https://api.superdocs.app; SID=PRINTED_SESSION; export OK="" NO=""; P=$(ls -t reply-$SID*.json | head -1); R=reply-$SID-$(date +%s).json
  K=$(python3 -c 'import json,sys;print(json.load(open(sys.argv[1]))["api_key"])' ~/.superdocs/agent_credentials.json)
  python3 -c 'import json,sys,os;d=json.load(open(sys.argv[1]))["document_changes"];no=os.environ.get("NO","").split();ok=[{"change_id":c["change_id"],"approved":c["change_id"] not in no} for c in d["pending_changes"] if c["change_id"] in no or not c.get("requires_review") or c["change_id"] in os.environ.get("OK","").split()];ok or sys.exit("nothing to approve");print(json.dumps({"job_id":d["job_id"],"approved":True,"wait_for_result":False,"changes":ok}))' $P > approve-$SID.json &&
  curl -sS --max-time 20 -X POST "$API/v1/chat/$SID/approve" -H "Authorization: Bearer $K" -H 'Content-Type: application/json' -d @approve-$SID.json -o ap-$SID.json &&
  python3 -c 'import json,sys;a=json.load(open(sys.argv[1]));print(a.get("message") or a);a.get("batch_complete") or sys.exit("STILL HELD: %s"%a.get("needs_individual_approval","") if "batch_complete" in a else "APPROVE FAILED: %s"%(a.get("detail") or a))' ap-$SID.json &&
  curl -sS --max-time 70 "$API/v1/sessions/$SID/result?wait_seconds=60&export_format=docx" -H "Authorization: Bearer $K" -o $R -w 'HTTP %{http_code}\n'
  ```
  Then the same two lines. Tell the user which held changes were NOT applied, naming each (they can ask again).
  * **STILL HELD** ids need their own call and the user's go: for each they approved, POST
    `{"job_id": J, "change_id": ID, "approved": true}` the same way, then wait; name the rest to the user.
    Never wait on a held job without deciding. **APPROVE FAILED**: do what its message says.
* **Follow-up**: `POST $API/v1/chat`, JSON: same `session_id`, `message`, `"response_mode": "summary"`, `"export_format": "docx"`.
* **Undo**: `POST $API/v1/sessions/$SID/revert` with `{"turn_index": N, "response_mode": "summary"}` (N from the reply).
  **Redo** (right after an undo): `POST $API/v1/sessions/$SID/redo` with `{"turn_index": N, "redo_checkpoint_id": "ID", "response_mode": "summary"}` (ID from the undo reply).

## Related

* [For AI Agents](https://docs.typebar.ai/introduction/agent-signup.md): sign-up, the API key and handing the account to a human.
* [Human-in-the-Loop](https://docs.typebar.ai/guides/human-in-the-loop.md): how held changes work.
* [Agent Editing Playbook](https://docs.typebar.ai/guides/agent-editing-playbook.md): editing patterns, placement, verification and billing.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.