---
title: "Library Push"
method: POST
path: "/library/push"
---

# Library Push

`POST /library/push`

## Request

- Base URL: `https://api-docs.session-exchange.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api-docs.session-exchange.com/library/push`
- Auth: none declared

One-call session save (for the agent-paste flow): POST the RAW transcript as the request
BODY (raw bytes — not JSON, not multipart), with `?label=`/`?title=` query params. The server
SCRUBS it and stages a PRIVATE collection wrapping it in the caller's personal library. The
library is resolved from the ACCOUNT (the session token), NOT the request Host — so this works
on the apex you logged in on; there is no subdomain to switch to. Authorization is implicit: a
signed-in human can only ever write to their OWN library. An agent can do the whole upload with
one HTTP request after a device-login — no local CLI, no multipart. Never promoted → stays private.

AUTH: a `ge_sess_` session bearer from the device-login. PERSIST that token so resuming later
needs no second login — `a4sx login --token <tok>` (writes ~/.config/a4sx/session, chmod 600), or
export A4SX_SESSION=<tok>. Clients look it up in this order: $A4SX_SESSION, $AGENT_MDX_SESSION,
~/.config/a4sx/session, then ~/.config/agent-mdx/session (where older sign-ins saved it). The same
token drives push, fetch, and resume.

RETRIES: send `Idempotency-Key: <uuid>` (one per logical push, the SAME on every retry of it) and
optionally `X-Content-SHA256: <hex sha256 of the body>`. A repeat of a key already answered within
24 h with the same bytes returns the ORIGINAL response (200) and stores nothing; the same key with
different bytes is `409 idempotency_key_reused`. Pushes to one entry are serialized, so a retry that
lands while the first is still being stored waits for it instead of racing it
(collector/push_idempotency.py).

WARNINGS: the response may carry an advisory `warnings: [{code, message}]` list; it never changes
the status or what is stored. `cli_outdated_pem` (#820): the body contains the client-side
`[REDACTED-PRIVATE-KEY]` marker and the client is an amdx/a4sx CLI <= 0.10.8 (or sends no a4sx
User-Agent), which may have merged transcript lines around that key (#816) — update and push again.

ASYNC (large uploads): send `Prefer: respond-async` and the server streams the body to disk, answers
`202 {job, status_url, ...}` at once and processes the push in the background; poll
`GET /library/push/jobs/{job}` until `status` is `done` (`result.http_status` + `result.body` = this
route's synchronous answer) or `failed` (`error`). Same scrub, same ledger, same answers
(collector/push_jobs.py). A retry with the same Idempotency-Key attaches to the running job.

## Response `200`

Successful Response

- unknown

---

[API](https://skmtc.dev/session-exchange/apis/a4sx.md) · [All operations](https://skmtc.dev/session-exchange/apis/a4sx/llms.txt) · [OpenAPI document](https://skmtc.dev/session-exchange/apis/a4sx/revisions/abaefc33dfc7?raw)
