API Docs/Reference/Get Bookmark
API Reference

Get Bookmark

Fetch a single saved post by its post_id.

GEThttps://api.linkedmash.com/v1/bookmarks/{id}

GET /v1/bookmarks/{id} fetches one saved post by its post_id — the numeric LinkedIn activity id that appears as post_id in list responses and at the end of a LinkedIn permalink. Use it to refresh a single record you already store, rather than re-listing a library to find one row.

The response is the same object shape a list item uses: post_details (text, link, posted_at, attachments), author_id and author_details, your tags, is_read, is_archived and sort_index. There is no partial or summary variant.

Example request

Authenticate with a bearer token in the Authorization header. Create a key on the API page in your LinkedMash settings and export it as LINKEDMASH_API_KEY before running this.

curl
curl "https://api.linkedmash.com/v1/bookmarks/7336731872414035968" \
  -H "Authorization: Bearer $LINKEDMASH_API_KEY"

Path parameters

idstringRequired

The post_id of the saved post to fetch.

Header parameters

AuthorizationstringRequired

Your secret API key as a Bearer token.

Response

{
  "status": true,
  "data": {
    "post_id": "7336731872414035968",
    "post_details": {
      "text": "Every single night, I run through a dead-simple 2-minute journal prompt.\n\nIt only has 5 questions.\n\nHere's how it works:",
      "link": "https://www.linkedin.com/feed/update/urn:li:activity:7336731872414035968",
      "posted_at": "2025-06-06T12:33:08.27+00:00",
      "attachments": []
    },
    "author_id": "urn:li:member:414777096",
    "author_details": {
      "bio": "I talk about digital writing & personal progress",
      "name": "Dickie Bush 🚢",
      "username": "member:414777096",
      "profile_image": {
        "url": "https://media.licdn.com/dms/image/v2/D4E03AQFjX-BmKVA8sw/profile-displayphoto-shrink_100_100/profile-displayphoto-shrink_100_100/0/1681174265529?e=1756339200&v=beta&t=dVOLCn5tuwDg8ZPO4N5lbb4gsKyKUjRDoZGp62QMi2I",
        "width": 100,
        "height": 100,
        "expiresAt": 1756339200000
      }
    },
    "tags": null,
    "is_read": false,
    "is_archived": false,
    "posted_at": "2025-06-06T12:33:08.27",
    "imported_at": "2025-06-13T06:13:08.373",
    "sort_index": "1749795181410"
  }
}

Response fields

Every response is wrapped in the same envelope: a status flag and a data payload, with meta present where there is pagination or a plan limit to report.

statusboolean

true on success. Every LinkedMash API response carries this envelope flag alongside data, so a client can branch on it without re-reading the HTTP status.

data.post_idstring

The LinkedIn activity id. It is the last path segment of a LinkedIn permalink and the value you pass to GET /v1/bookmarks/{id} and to the label endpoints.

data.post_details.textstring

The full post body as saved, including line breaks and emoji. Not truncated.

data.post_details.linkstring

Canonical LinkedIn permalink for the post.

data.post_details.posted_atstring

ISO-8601 timestamp of when the author published the post on LinkedIn.

data.post_details.attachmentsarray

Media and link previews carried by the post. Each entry has a type (image, video, article, document), a title, a url, and a thumbnail array of sized image variants.

data.author_idstring

LinkedIn identifier for the author, stable across posts, so you can group a library by writer.

data.author_details.namestring

The author's display name.

data.author_details.usernamestring

The public LinkedIn vanity handle, i.e. the /in/ segment of their profile URL.

data.author_details.biostring

The headline shown under the name on LinkedIn. This is the field most integrations use to infer role and company.

data.author_details.profile_imageobject

url, width, height and expiresAt. The URL is a LinkedIn CDN address that stops resolving after expiresAt — re-host it if you need it to persist.

data.tagsarray

The label names you have applied to this post. Empty when the post is untagged.

data.is_readboolean

Whether the post has been marked read in LinkedMash. Both read and unread posts are returned unless you set is_unread_only.

data.is_archivedboolean

Whether the post has been archived. Archived posts are hidden from list results by default.

data.posted_atstring

Same as post_details.posted_at, lifted to the top level for sorting. This is the field to sort on — not created_at, which reflects when the record entered LinkedMash.

data.imported_atstring

ISO-8601 timestamp of when LinkedMash first pulled the post into the library.

data.sort_indexstring

Opaque ordering key. The encoded form of the last item’s sort_index is exactly what meta.next_cursor contains.

Refreshing a stored post

Use this when you already hold a post_id and want current state, rather than re-listing to find one row.

1

Keep the post_id from the list call

post_id is stable — it is the LinkedIn activity id, not a LinkedMash row id — so it stays valid across syncs and is safe to use as a foreign key in your own store.

2

Re-read for tags and state

Labels, is_read and is_archived change in the app after you have synced. This route reflects them immediately, and it returns archived and read posts that the list endpoint would have filtered out.

3

Treat 404 as deleted

A post removed from the library is indistinguishable from one that was never there. If your store has the id and this returns 404, the user deleted it.

4

Re-host the avatar

author_details.profile_image.url expires. If you are rendering the author anywhere persistent, copy the image on first read rather than storing the URL.

Behaviour and limits

Read and archive state do not hide a post

This route deliberately ignores the unread and archived filters, so an archived or already-read post still resolves. That makes it safe to use as a by-id refresh for anything you have stored, whatever the user has since done to it in the app.

A missing id is a 404, not an empty 200

If the post_id is not in this account's library the response is 404 with "Saved post not found." An id that belongs to a different account looks identical, because every query is scoped to the key's account.

Not subscription-gated

Single-post reads work on a free key. The free-tier cap applies to listing, not to fetching a post you can already name.

profile_image URLs expire

author_details.profile_image is a LinkedIn CDN URL with an expiresAt timestamp. Re-host it if you need it to survive; do not cache the URL as permanent.

Errors

Failures carry the same envelope as a success, with the reason in message and a stable machine-readable code where the status alone is ambiguous — several distinct conditions share a 402.

Status
Meaning
400Bad Request
The id path segment was empty.
401Unauthorized
The Authorization header is missing or the key is not a valid LinkedMash API key. Create or rotate keys on the API page in your LinkedMash settings.
404Not Found
No saved post with that post_id exists in this account.
500Server Error
Something failed on our side. The body carries message "Failed to get bookmark". Retry once; if it persists the request is not the problem.