Skip to content

Add (or re-pin) an existing post in a collection

POST
/collections/{id}/posts

Adds a REFERENCE, never a copy (#882). The post keeps its author, its visibility and its lifecycle; the collection holds a pointer. If the author deletes the post it disappears from every collection that referenced it (collection_posts_post_id_fkey … ON DELETE CASCADE), which is the point: “the owner can still delete it from everywhere”.

Idempotent on (collection_id, post_id). Re-adding an existing membership updates sort_order, pinned and expires_at but keeps added_at fixed.

You may only collect what you can actually read. The post must pass the same read rule GET /posts/{id} applies — so anyone can pin an org-only post, only a follower can pin a followers-tier one, and a stranger’s private post cannot be pinned at all. A post the caller may not read is reported exactly as one that does not exist: 404 with post not found, so this endpoint cannot be used to probe whether a UUID exists.

The collection must be one the caller may mutate. An absent collection, a soft-deleted one and someone else’s are all 404 here — unlike the asset route, which grandfathers a distinguishable 403.

id
required
string format: uuid

The body of POST /collections/{id}/posts (#882), and the only membership a caller writes. It used to mirror CollectionResourceWrite field for field, because collection_posts and collection_resources carry the same membership columns — a reference plus the curator’s ordering. That schema went with its write endpoints in #1161 and the read side (CollectionResource) with #1236: a collection holds posts.

There is no narrower post-membership shape on the read side either — GET /collections/{id}/posts returns whole Post objects, so the collection page renders the same PostCard as browse rather than a second shape that would drift from it.

object
post_id
required
string format: uuid
sort_order
integer
0
pinned
boolean
default: true
expires_at
string format: date-time
nullable

Post added

Malformed request

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Authentication required, missing, or invalid

object
error
required

Human-readable error summary

string
Example
the request could not be completed
Example
{
"error": "authentication required: sign in and retry with a valid session or API token"
}

Resource not found

object
error
required

Human-readable error summary

string
Example
the request could not be completed