Publishing to LinkedIn Is a State Machine
Building the x70 LinkedIn desk made the remote API call look like the easy part; truthful research, human approval, scheduling, reconnection, and remote publication all need distinct states.
In July I added a personal LinkedIn publishing desk to x70 Admin.
The smallest implementation would have been a textarea connected directly to LinkedIn’s Posts API. That would make a demo easy and routine use stressful. A draft needs somewhere to live before it becomes a remote post, and an automated research system should not inherit publishing authority merely because it can produce fluent text.
The resulting product is a state machine with an explicit human gate.
LinkedIn is the publication target, not the draft store
LinkedIn’s official Posts API
documentation
describes creating organic and sponsored posts and shows creation requests with
the lifecycle state PUBLISHED. The x70 desk therefore keeps its own editorial
state in Convex until the final remote operation.
The main path is:
draft → approved → scheduled → publishing → published
Failure states are equally important. A scheduled post can be cancelled. A
publish attempt can fail. An expired or revoked connection can move the item to
needs_reconnect rather than repeatedly retrying with an invalid credential.
The UI can now tell the author what kind of problem exists instead of calling everything “pending.”
Research should produce evidence before prose
The idea workflow starts with live web research and a source dossier. It keeps the URLs and verification time attached to the idea so the author can inspect where a claim came from.
Only then does the writer produce a concise personal draft. A later fact-check revisits the source-backed statements before the post can move toward approval.
That process cannot guarantee truth. Search results can be incomplete, a source can change, and a model can connect evidence to the wrong sentence. The purpose of the dossier is to make those failures reviewable and to stop unsupported angles before they turn into polished copy.
Time-sensitive evidence also expires. Rerunning research is more honest than publishing a “current” model or product claim from an old snapshot.
Approval changes capability
Nothing publishes from the composer.
The composer can help write, shorten, or restructure the post. It can prepare an article link or media. Saving creates or updates a draft. A separate action records approval, after which the item becomes schedulable.
This is stronger than an instruction telling the model not to publish. Before approval, the workflow simply has no path to the publishing queue. The product boundary carries the policy.
The same rule applies to generated images. A draft graphic and alt text remain review material; they are not remote media merely because generation finished.
Scheduling needs a lock and a ledger
At the scheduled time, a Convex job claims the item and moves it into
publishing. The lock prevents two workers from sending the same post. The
result stores the returned LinkedIn URN on success or a structured failure on
error.
That ledger lets the Admin distinguish what it intended from what LinkedIn accepted. Closing a browser does not cancel the schedule, and reopening the calendar does not create a second timer.
Connection health is part of the same flow. OAuth tokens are encrypted in the backend, and publishing pauses when the personal-profile connection needs to be renewed. The UI shows that condition rather than treating it as a generic post failure.
Remote engagement is not ours to manufacture
The application requests the scopes needed for sign-in and personal publishing. It does not pretend to have broad member analytics or automatic access to every reaction and comment.
More importantly, it does not create likes or comments to make a post look successful. Engagement belongs to the people on the remote network. The desk can prove that a reviewed post was submitted and retain the returned identifier; it cannot honestly promise a response.
That separation keeps the metrics from corrupting the workflow. The success criteria before publication are evidence, editorial approval, a valid schedule, and a confirmed API result—not an invented audience outcome.
The API call is the final step
Most of the product exists before the POST request: research, sources, drafting, revision, media, approval, scheduling, locking, connection health, and audit history.
That is the lesson I am keeping. External publishing is not one button with a token behind it. It is a sequence of authority changes, and the interface should make every one of them visible.