An API timeout means the client stopped waiting. It does not mean the server stopped working, the social provider rejected the Post, or nothing was published.
That ambiguity is the central recovery problem. A client that treats every timeout as failure can duplicate public content. A client that treats every timeout as success can silently lose it.
Four places a timeout can happen
Before the service receives the request
The connection may fail before the server accepts any bytes. A retry is usually necessary, but the client may not be able to prove this is where the failure happened.
After the service creates the Post
The server may persist the Post and lose the response on the way back. Retrying without idempotency can create a second resource.
While media or provider work continues
Video preparation and provider uploads may take longer than one HTTP request. The correct response is often a stable resource in preparing, queued, or publishing state, not an open connection until the provider finishes.
After the provider accepts the Post
The social platform may publish successfully while the service is waiting for a receipt or reconciling the remote object. A blind retry at this point is the most visible failure mode.
The information a client needs
A recoverable API gives the client several independent handles:
| Evidence | What it answers |
|---|---|
| Idempotency key | Is this the same logical write? |
| Request ID | Which server request should support or logs inspect? |
| Stable Post ID | Which resource can the client read again? |
| State and attempt count | Is work pending, completed, retryable, or terminal? |
| Per-Destination result | Which target succeeded or failed? |
| Provider receipt | What remote object was created? |
| Signed webhook | What changed after the original response? |
No single field replaces the others. A request ID helps diagnose the call but may not identify the logical Post. A Post ID identifies the resource but does not prevent a second create. A webhook reports later state but must be authenticated.
A safe recovery policy
When a publish call times out:
- Do not create a new idempotency key.
- If a stable Post ID is known, read its current state.
- If the state is pending, wait for the documented terminal transition or signed webhook.
- If the state is failed and retryable, call the documented retry operation.
- If no Post ID is known, repeat the original request with the same key.
- Escalate ambiguous or mismatched state instead of guessing.
The service should also distinguish a transient provider failure from a permanent input or authorization problem. Retrying an expired OAuth grant or invalid media file does not make it valid.
Partial success needs its own answer
A multi-Destination request can publish to Bluesky and Mastodon while LinkedIn remains pending. A thread can publish its first two items and fail on the third.
The API should preserve completed work and expose the unresolved part. A retry should resume or reconcile the remainder. Replaying every successful item because one target failed turns a recoverable incident into duplicate public content.
Timeouts are a contract test
The important question is not whether an API ever times out. Networks, media processors, and social providers all have variable latency. The question is whether a client can determine what happened without relying on hope, string matching, or a human checking every network manually.
OpenPMM documents errors and request IDs, Post state and retries, and signed webhook events. Those publishing semantics are available through hosted MCP, the API, and the CLI. The broader evaluation is in the production-readiness checklist.