{"openapi":"3.1.1","jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","info":{"title":"LinkedMash API","version":"1.0.0","description":"The public LinkedMash API for retrieving saved LinkedIn posts, managing labels and drafts, scheduling content, and reading analytics.","license":{"name":"LinkedMash Terms of Service","url":"https://www.linkedmash.com/terms"},"contact":{"name":"LinkedMash Support","email":"support@linkedmash.com","url":"https://www.linkedmash.com/api-docs/getting-started"}},"servers":[{"url":"https://api.linkedmash.com","description":"LinkedMash production API"}],"tags":[{"name":"Bookmarks","description":"Search, count, and retrieve saved LinkedIn posts and comments."},{"name":"Labels","description":"List labels and apply or remove them from saved posts."},{"name":"Drafts","description":"Create, inspect, update, delete, and schedule LinkedIn post drafts."},{"name":"Media","description":"Upload or re-host media for a LinkedIn post draft."},{"name":"Queue","description":"Inspect, cancel, and reschedule queued LinkedIn posts."},{"name":"Schedule","description":"Read and update the account posting schedule."},{"name":"Analytics","description":"Read account-level and post-level LinkedIn performance metrics."}],"externalDocs":{"description":"LinkedMash API documentation","url":"https://www.linkedmash.com/api-docs/getting-started"},"paths":{"/v1/bookmarks":{"get":{"tags":["Bookmarks"],"summary":"Fetch Saved Posts","description":"Retrieve all the bookmarks that you've created. You can use the query parameters to filter and paginate results.\n\nGET /v1/bookmarks is the endpoint most integrations start with. It returns the LinkedIn posts (and saved comments) the authenticated account has collected in LinkedMash, newest first, as a cursor-paginated list. Each item carries the post text, permalink, attachments, the author's name, bio and profile image, your labels, read and archive state, and both posted_at and imported_at timestamps — enough to mirror a library into another system without a second call.\n\nThe same filters the LinkedMash web app uses are exposed here, and they behave identically: read and unread posts are both returned unless you ask otherwise, and archived posts are hidden by default. Keyword search (q) matches post content; vector_search_term runs semantic search over the same library and needs a vector store that has been initialised at least once.","operationId":"fetchSavedPosts","externalDocs":{"description":"Fetch Saved Posts documentation","url":"https://www.linkedmash.com/api-docs/fetch-saved-posts"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"The maximum number of bookmarks to return. Default is 20, maximum is 100.","schema":{"type":"integer","example":20}},{"name":"cursor","in":"query","required":false,"description":"Cursor for pagination. Use the next_cursor value from a previous response.","schema":{"type":"string"}},{"name":"is_unread_only","in":"query","required":false,"description":"Return only unread posts. Defaults to false — read and unread are both returned unless you set this to true.","schema":{"type":"boolean"}},{"name":"hide_archived","in":"query","required":false,"description":"Filter by archived status. Default is true (hides archived bookmarks).","schema":{"type":"boolean"}},{"name":"media_type","in":"query","required":false,"description":"Filter by media type. Must be one of image, video or pdf; any other value returns 400. Paid plans.","schema":{"type":"string"}},{"name":"comment","in":"query","required":false,"description":"Filter by comment: 'only' returns just saved comments, 'exclude' returns only top-level posts (excludes comments). Paid plans.","schema":{"type":"string"}},{"name":"author","in":"query","required":false,"description":"Filter by author name.","schema":{"type":"string","example":"Dickie Bush"}},{"name":"tag","in":"query","required":false,"description":"Filter by tag.","schema":{"type":"string"}},{"name":"posted_from","in":"query","required":false,"description":"Filter bookmarks posted after this date/time (ISO 8601 format).","schema":{"type":"string","format":"date-time","example":"2026-01-01T00:00:00Z"}},{"name":"posted_to","in":"query","required":false,"description":"Filter bookmarks posted before this date/time (ISO 8601 format).","schema":{"type":"string","format":"date-time"}},{"name":"bookmarked_from","in":"query","required":false,"description":"Filter bookmarks created after this date/time (ISO 8601 format).","schema":{"type":"string","format":"date-time"}},{"name":"bookmarked_to","in":"query","required":false,"description":"Filter bookmarks created before this date/time (ISO 8601 format).","schema":{"type":"string","format":"date-time"}},{"name":"sort_by","in":"query","required":false,"description":"Field to sort by (e.g., 'created_at', 'title').","schema":{"type":"string"}},{"name":"sort_cursor","in":"query","required":false,"description":"Value of the sort field from the last item of the previous page, used for stable sorting with pagination.","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Search query to filter bookmarks by title or content.","schema":{"type":"string"}},{"name":"vector_search_term","in":"query","required":false,"description":"Vector search term for semantic search.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data","meta"],"properties":{"status":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["post_id","post_details","author_id","author_details","tags","is_read","is_archived","posted_at","imported_at","sort_index"],"properties":{"post_id":{"type":"string"},"post_details":{"type":"object","additionalProperties":false,"required":["text","link","posted_at","attachments"],"properties":{"text":{"type":"string"},"link":{"type":"string","format":"uri"},"posted_at":{"type":"string","format":"date-time"},"attachments":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["type","title","url","thumbnail"],"properties":{"type":{"type":"string"},"title":{"type":"string"},"url":{"type":"string","format":"uri"},"thumbnail":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["url","width","height"],"properties":{"url":{"type":"string","format":"uri"},"width":{"type":"integer"},"height":{"type":"integer"}}}}}}}}},"author_id":{"type":"string"},"author_details":{"type":"object","additionalProperties":false,"required":["bio","name","username","profile_image"],"properties":{"bio":{"type":"string"},"name":{"type":"string"},"username":{"type":"string"},"profile_image":{"type":"object","additionalProperties":false,"required":["url","width","height","expiresAt"],"properties":{"url":{"type":"string","format":"uri"},"width":{"type":"integer"},"height":{"type":"integer"},"expiresAt":{"type":"integer"}}}}},"tags":{},"is_read":{"type":"boolean"},"is_archived":{"type":"boolean"},"posted_at":{"type":"string"},"imported_at":{"type":"string"},"sort_index":{"type":"string"}}}},"meta":{"type":"object","additionalProperties":false,"required":["next_cursor","limit","total_count"],"properties":{"next_cursor":{"type":"string"},"limit":{"type":"integer"},"total_count":{"type":"integer"}}}}},"example":{"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":[{"type":"document","title":"My 2-Minute Evening Journal Prompt (5 Questions)","url":"https://media.licdn.com/dms/document/media/v2/D4E1FAQF_Jxg36sxpIg/feedshare-document-pdf-analyzed/B4EZdFOIHNGcAc-/0/1749213108945?e=1750291200&v=beta&t=HmRZA2gVOuUaGdOqfKz5WDWcnJ_fKWYSv-hXEhg4WvA","thumbnail":[{"url":"https://media.licdn.com/dms/document/pl/v2/D4E1FAQF_Jxg36sxpIg/feedshare-document-images_1920/B4EZdFOIHNGcAY-/0/1749213108945?e=1750291200&v=beta&t=UTLn8IylWinjDWp31RgkPOa-ImYgdpePUEclQuy-xjw","width":1545,"height":1931}]}]},"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"}],"meta":{"next_cursor":"MTc1OTYxNw==","limit":1,"total_count":396}}}}},"400":{"description":"Bad Request. Invalid media_type, invalid comment value, a non-positive limit, or a cursor that could not be decoded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","message"],"properties":{"status":{"type":"boolean"},"message":{"type":"string"}}},"example":{"status":false,"message":"Unauthorized"}}}},"402":{"description":"Payment Required. Code FILTER_NOT_ALLOWED, PAGINATION_NOT_ALLOWED or VECTOR_SEARCH_NOT_ALLOWED — a free key reached for a paid capability.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","message"],"properties":{"status":{"type":"boolean"},"message":{"type":"string"}}},"example":{"status":false,"message":"Subscription Required"}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to list bookmarks\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/bookmarks/count":{"get":{"tags":["Bookmarks"],"summary":"Count Saved Posts","description":"Get the total count of bookmarks for the authenticated user.\n\nGET /v1/bookmarks/count returns how many saved posts match a filter, without transferring the posts themselves. It accepts the same filter set as GET /v1/bookmarks, so you can size a query before you page through it — useful for progress bars, sync planning, or deciding whether a nightly job has anything to do.\n\nThe response echoes an applied_filters object alongside the count. That is deliberate: a count with no record of what it counted is easy to misread, and echoing the resolved filters lets a caller assert that the number covers what it thinks it covers.","operationId":"countSavedPosts","externalDocs":{"description":"Count Saved Posts documentation","url":"https://www.linkedmash.com/api-docs/count-saved-posts"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"is_unread_only","in":"query","required":false,"description":"Count only unread posts. Defaults to false — read and unread are both counted unless you set this to true.","schema":{"type":"boolean"}},{"name":"hide_archived","in":"query","required":false,"description":"Exclude archived posts. Defaults to true, matching GET /v1/bookmarks so list and count always agree.","schema":{"type":"boolean"}},{"name":"media_type","in":"query","required":false,"description":"Filter by media type. Must be one of image, video or pdf; any other value returns 400. Paid plans.","schema":{"type":"string","example":"video"}},{"name":"author","in":"query","required":false,"description":"Filter by author name.","schema":{"type":"string"}},{"name":"tag","in":"query","required":false,"description":"Filter by tag.","schema":{"type":"string"}},{"name":"posted_from","in":"query","required":false,"description":"Filter bookmarks posted after this date/time (ISO 8601 format).","schema":{"type":"string","format":"date-time","example":"2026-01-01T00:00:00Z"}},{"name":"posted_to","in":"query","required":false,"description":"Filter bookmarks posted before this date/time (ISO 8601 format).","schema":{"type":"string","format":"date-time"}},{"name":"bookmarked_from","in":"query","required":false,"description":"Filter bookmarks created after this date/time (ISO 8601 format).","schema":{"type":"string","format":"date-time"}},{"name":"bookmarked_to","in":"query","required":false,"description":"Filter bookmarks created before this date/time (ISO 8601 format).","schema":{"type":"string","format":"date-time"}},{"name":"q","in":"query","required":false,"description":"Search query to filter bookmarks by title or content.","schema":{"type":"string"}},{"name":"comment","in":"query","required":false,"description":"Filter by comment: 'only' returns just saved comments, 'exclude' returns only top-level posts (excludes comments). Paid plans.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["count"],"properties":{"count":{"type":"integer"}}}}},"example":{"status":true,"data":{"count":123}}}}},"400":{"description":"Bad Request. Invalid media_type or an invalid comment value.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","message"],"properties":{"status":{"type":"boolean"},"message":{"type":"string"}}},"example":{"status":false,"message":"Unauthorized"}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to count bookmarks\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","message"],"properties":{"status":{"type":"boolean"},"message":{"type":"string"}}},"example":{"status":false,"message":"Failed to validate API key"}}}}}}},"/v1/labels":{"get":{"tags":["Labels"],"summary":"List Labels","description":"List all labels for the authenticated user.\n\nGET /v1/labels returns every label on the authenticated account, each with its numeric id, label_name and a metadata object. Labels are LinkedMash's tagging layer over saved posts; the ids returned here are what you pass as label_id when adding or removing labels in bulk.\n\nThis is the call to make before any labelling workflow, because it tells you which names already exist. Adding by label_name will create a label that is not in this list, so reading first is how you avoid ending up with 'AI', 'ai' and 'A.I.' as three separate labels.","operationId":"listLabels","externalDocs":{"description":"List Labels documentation","url":"https://www.linkedmash.com/api-docs/list-labels"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","label_name","metadata"],"properties":{"id":{"type":"integer"},"label_name":{"type":"string"},"metadata":{"type":"object","additionalProperties":true}}}}}},"example":{"status":true,"data":[{"id":871042907,"label_name":"Motivation","metadata":{}},{"id":137703742,"label_name":"Visuals","metadata":{}},{"id":586565281,"label_name":"Learning","metadata":{}}]}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","message"],"properties":{"status":{"type":"boolean"},"message":{"type":"string"}}},"example":{"status":false,"message":"Unauthorized"}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to list all user labels\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","message"],"properties":{"status":{"type":"boolean"},"message":{"type":"string"}}},"example":{"status":false,"message":"Failed to list all user labels"}}}}}}},"/v1/labels/add":{"post":{"tags":["Labels"],"summary":"Add Labels to Bookmarks","description":"Add one or more labels to user bookmarks.\n\nPOST /v1/labels/add attaches a label to one or many saved posts in a single call. Identify the label either by label_id (from GET /v1/labels) or by label_name, and pass post_ids as an array — or a single id, which is accepted for convenience and treated as an array of one.\n\nThis is the bulk primitive behind every classification workflow: fetch a filtered page from /v1/bookmarks, decide a label, and write it back in one request rather than one call per post.","operationId":"addLabelsToBookmarks","externalDocs":{"description":"Add Labels to Bookmarks documentation","url":"https://www.linkedmash.com/api-docs/add-labels-to-bookmarks"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["post_ids"],"properties":{"post_ids":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"string"}],"example":["7336731872414035968","7331104558812631041"],"description":"IDs of the posts to label."},"label_id":{"type":"string","description":"ID of the label to add."},"label_name":{"type":"string","example":"Hooks","description":"Name of the label to add (if creating a new one)."}}},"example":{"post_ids":["7336731872414035968","7331104558812631041"],"label_name":"Hooks"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data","message"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["success"],"properties":{"success":{"type":"boolean"}}},"message":{"type":"string"}}},"example":{"status":true,"data":{"success":true},"message":"Labels added to bookmarks"}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","message"],"properties":{"status":{"type":"boolean"},"message":{"type":"string"}}},"example":{"status":false,"message":"Unauthorized"}}}},"402":{"description":"Payment Required. Code SUBSCRIPTION_REQUIRED — labelling requires an active subscription.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to add labels to bookmarks\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","message"],"properties":{"status":{"type":"boolean"},"message":{"type":"string"}}},"example":{"status":false,"message":"Failed to add labels to bookmarks"}}}}}}},"/v1/labels/remove":{"post":{"tags":["Labels"],"summary":"Remove Labels from Bookmarks","description":"Remove one or more labels from user bookmarks.\n\nPOST /v1/labels/remove detaches a label from one or many saved posts. It mirrors /v1/labels/add: identify the label by label_id or label_name, pass post_ids, and the removal is applied across the whole set in one request.\n\nThe response is more informative than the add path because removal has two distinct non-error outcomes. meta carries removed, requested and removed_post_ids, so you can tell 'removed from 3 of 5' apart from 'none of those posts carried that label' without diffing state yourself.","operationId":"removeLabelsFromBookmarks","externalDocs":{"description":"Remove Labels from Bookmarks documentation","url":"https://www.linkedmash.com/api-docs/remove-labels-from-bookmarks"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["post_ids"],"properties":{"post_ids":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"string"}],"example":["7336731872414035968"],"description":"IDs of the posts to remove labels from."},"label_id":{"type":"string","description":"ID of the label to remove."},"label_name":{"type":"string","example":"Hooks","description":"Name of the label to remove."}}},"example":{"post_ids":["7336731872414035968"],"label_name":"Hooks"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data","message"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["success"],"properties":{"success":{"type":"boolean"}}},"message":{"type":"string"}}},"example":{"status":true,"data":{"success":true},"message":"Labels removed from bookmarks"}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","message"],"properties":{"status":{"type":"boolean"},"message":{"type":"string"}}},"example":{"status":false,"message":"Unauthorized"}}}},"402":{"description":"Payment Required. Code SUBSCRIPTION_REQUIRED — label removal requires an active subscription.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found. The label_name could not be resolved to a label on this account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to remove labels from bookmarks\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","message"],"properties":{"status":{"type":"boolean"},"message":{"type":"string"}}},"example":{"status":false,"message":"Failed to remove labels from bookmarks"}}}}}}},"/v1/bookmarks/{id}":{"get":{"tags":["Bookmarks"],"summary":"Get Bookmark","description":"Fetch a single saved post by its post_id.\n\nGET /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.\n\nThe 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.","operationId":"getBookmark","externalDocs":{"description":"Get Bookmark documentation","url":"https://www.linkedmash.com/api-docs/get-bookmark"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The post_id of the saved post to fetch.","schema":{"type":"string","example":"7336731872414035968"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["post_id","post_details","author_id","author_details","tags","is_read","is_archived","posted_at","imported_at","sort_index"],"properties":{"post_id":{"type":"string"},"post_details":{"type":"object","additionalProperties":false,"required":["text","link","posted_at","attachments"],"properties":{"text":{"type":"string"},"link":{"type":"string","format":"uri"},"posted_at":{"type":"string","format":"date-time"},"attachments":{"type":"array","items":{"type":"object","description":"Saved LinkedIn attachment or link preview.","properties":{"type":{"type":"string"},"title":{"type":"string"},"url":{"type":"string","format":"uri"},"thumbnail":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"width":{"type":"integer"},"height":{"type":"integer"}}}}}}}}},"author_id":{"type":"string"},"author_details":{"type":"object","additionalProperties":false,"required":["bio","name","username","profile_image"],"properties":{"bio":{"type":"string"},"name":{"type":"string"},"username":{"type":"string"},"profile_image":{"type":"object","additionalProperties":false,"required":["url","width","height","expiresAt"],"properties":{"url":{"type":"string","format":"uri"},"width":{"type":"integer"},"height":{"type":"integer"},"expiresAt":{"type":"integer"}}}}},"tags":{},"is_read":{"type":"boolean"},"is_archived":{"type":"boolean"},"posted_at":{"type":"string"},"imported_at":{"type":"string"},"sort_index":{"type":"string"}}}}},"example":{"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"}}}}},"400":{"description":"Bad Request. The id path segment was empty.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"404":{"description":"Not Found. No saved post with that post_id exists in this account.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"NOT_FOUND","error":"Saved post not found."}}}},"500":{"description":"Server 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.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/posts":{"post":{"tags":["Drafts"],"summary":"Create Draft","description":"Create a new post draft. Attach media by setting post_type and one of media_url or media_urls. Requires a paid Creator or Lifetime plan.\n\nPOST /v1/posts creates a LinkedIn post draft in LinkedMash. content is the only required field; everything else — title, format, and the media fields — is optional. The draft is created unscheduled, so nothing is published by this call, and the returned id is what you pass to the schedule, update and delete endpoints.\n\nTo attach media, upload or re-host it first with POST /v1/media/upload and pass the returned URL as media_url (or several as media_urls), together with post_type and media_mime_type. Passing a LinkedIn-hosted or short-lived URL directly is the usual cause of a draft that publishes without its image.","operationId":"createDraft","externalDocs":{"description":"Create Draft documentation","url":"https://www.linkedmash.com/api-docs/create-draft"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["content"],"properties":{"content":{"type":"string","example":"5 lessons from shipping every week for a year:","description":"The post body text."},"title":{"type":"string","example":"Weekly shipping lessons","description":"An optional title for the draft."},"format":{"type":"string","example":"text","description":"Post format: text, image, video, article, or poll."},"post_type":{"type":"string","description":"Media type to attach: text, image, video, or pdf. Set this when attaching media."},"media_url":{"type":"string","format":"uri","description":"Public URL of an image, video, or PDF to attach."},"media_urls":{"type":"array","items":{"type":"string","format":"uri"},"description":"Multiple public media URLs to attach."},"media_mime_type":{"type":"string","description":"MIME type of the attached media (e.g., 'image/png')."}}},"example":{"content":"5 lessons from shipping every week for a year:","title":"Weekly shipping lessons","format":"text"}}}},"responses":{"201":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["id","content","title","format","status","created_at","updated_at"],"properties":{"id":{"type":"string"},"content":{"type":"string"},"title":{"type":"string"},"format":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}},"example":{"status":true,"data":{"id":"drf_8f3a21c9","content":"5 lessons from shipping every week for a year:","title":"Weekly shipping lessons","format":"text","status":"draft","created_at":"2026-06-22T09:14:02.118Z","updated_at":"2026-06-22T09:14:02.118Z"}}}}},"400":{"description":"Bad Request. content was missing or empty.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to create post\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"tags":["Drafts"],"summary":"List Drafts","description":"List your post drafts, optionally filtered by status. Requires a paid Creator or Lifetime plan.\n\nGET /v1/posts lists the account's post drafts. With no query string you get everything the Studio holds; pass status to narrow to draft, scheduled or published. The response is a flat array in data with meta.count alongside it.\n\nUse this to reconcile an external content calendar with LinkedMash, or to find the draft ids you need for the schedule and update endpoints when you did not keep them from the create call.","operationId":"listDrafts","externalDocs":{"description":"List Drafts documentation","url":"https://www.linkedmash.com/api-docs/list-drafts"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"Filter by status: draft, scheduled, or published.","schema":{"type":"string","example":"draft"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data","meta"],"properties":{"status":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","content","title","format","status","created_at","updated_at"],"properties":{"id":{"type":"string"},"content":{"type":"string"},"title":{"type":"string"},"format":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","additionalProperties":false,"required":["count"],"properties":{"count":{"type":"integer"}}}}},"example":{"status":true,"data":[{"id":"drf_8f3a21c9","content":"5 lessons from shipping every week for a year:","title":"Weekly shipping lessons","format":"text","status":"draft","created_at":"2026-06-22T09:14:02.118Z","updated_at":"2026-06-22T09:14:02.118Z"}],"meta":{"count":1}}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to list posts\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/posts/{id}":{"get":{"tags":["Drafts"],"summary":"Get Draft","description":"Fetch a single post draft by its id. Requires a paid Creator or Lifetime plan.\n\nGET /v1/posts/{id} returns a single draft by id, including its content, title, format, status, any attached media and its timestamps. It is the read half of the update loop: fetch, modify, PATCH back.\n\nThe id is the value returned as data.id when the draft was created, and the same id used by the schedule and delete routes.","operationId":"getDraft","externalDocs":{"description":"Get Draft documentation","url":"https://www.linkedmash.com/api-docs/get-draft"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The id of the draft to fetch.","schema":{"type":"string","example":"drf_8f3a21c9"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["id","content","title","format","status","created_at","updated_at"],"properties":{"id":{"type":"string"},"content":{"type":"string"},"title":{"type":"string"},"format":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}},"example":{"status":true,"data":{"id":"drf_8f3a21c9","content":"5 lessons from shipping every week for a year:","title":"Weekly shipping lessons","format":"text","status":"draft","created_at":"2026-06-22T09:14:02.118Z","updated_at":"2026-06-22T09:14:02.118Z"}}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"404":{"description":"Not Found. No draft with that id on this account.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"NOT_FOUND","error":"Draft not found."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to get post\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Drafts"],"summary":"Update Draft","description":"Update an existing draft. content is required unless you are only trashing the draft. Requires a paid Creator or Lifetime plan.\n\nPATCH /v1/posts/{id} updates an existing draft. It is a partial update in intent — send only the fields you want to change — and the same media rules as create apply: post_type plus media_url or media_urls, with media_mime_type where the type is not obvious from the URL.\n\nThe route first fetches the draft to confirm it exists and belongs to the key's account, so a bad id fails cleanly as a 404 instead of creating something or writing to the wrong record.","operationId":"updateDraft","externalDocs":{"description":"Update Draft documentation","url":"https://www.linkedmash.com/api-docs/update-draft"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Identifier of the requested resource.","schema":{"type":"string","example":"drf_8f3a21c9"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["content"],"properties":{"content":{"type":"string","example":"5 lessons from shipping every week for a year (rewritten hook):","description":"The post body text. Required unless only trashing the draft."},"title":{"type":"string","description":"An optional title for the draft."},"format":{"type":"string","example":"text","description":"Post format: text, image, video, article, or poll."},"post_type":{"type":"string","description":"Media type to attach: text, image, video, or pdf. Set this when attaching media."},"media_url":{"type":"string","format":"uri","description":"Public URL of an image, video, or PDF to attach."},"media_urls":{"type":"array","items":{"type":"string","format":"uri"},"description":"Multiple public media URLs to attach."},"media_mime_type":{"type":"string","description":"MIME type of the attached media (e.g., 'image/png')."}}},"example":{"content":"5 lessons from shipping every week for a year (rewritten hook):","format":"text"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["id","content","title","format","status","created_at","updated_at"],"properties":{"id":{"type":"string"},"content":{"type":"string"},"title":{"type":"string"},"format":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}},"example":{"status":true,"data":{"id":"drf_8f3a21c9","content":"5 lessons from shipping every week for a year (updated):","title":"Weekly shipping lessons","format":"text","status":"draft","created_at":"2026-06-22T09:14:02.118Z","updated_at":"2026-06-22T10:02:51.640Z"}}}}},"400":{"description":"Bad Request. The draft store rejected the payload — most often an empty content field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"404":{"description":"Not Found. No draft with that id on this account.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"NOT_FOUND","error":"Draft not found."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to update post\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Drafts"],"summary":"Delete Draft","description":"Delete a post draft by its id. Requires a paid Creator or Lifetime plan.\n\nDELETE /v1/posts/{id} removes a draft. The delete is soft: the draft is moved to trash rather than erased, which is why the response is a plain { id, deleted: true } rather than the deleted record.\n\nAs with update, the draft is fetched first to confirm it exists and belongs to the account, so deleting an unknown id is a clean 404.","operationId":"deleteDraft","externalDocs":{"description":"Delete Draft documentation","url":"https://www.linkedmash.com/api-docs/delete-draft"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The id of the draft to delete.","schema":{"type":"string","example":"drf_8f3a21c9"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["id","deleted"],"properties":{"id":{"type":"string"},"deleted":{"type":"boolean"}}}}},"example":{"status":true,"data":{"id":"drf_8f3a21c9","deleted":true}}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"404":{"description":"Not Found. No draft with that id on this account.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"NOT_FOUND","error":"Draft not found."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to delete post\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/media/upload":{"post":{"tags":["Media"],"summary":"Upload Media","description":"Re-host an image, video, or PDF for use in a post. Provide either url or file_base64, not both. Requires a paid Creator or Lifetime plan.\n\nPOST /v1/media/upload re-hosts an image, video or PDF on LinkedMash and returns a stable public URL to use as media_url on a draft or a schedule call. It takes either a remote url to fetch and copy, or file_base64 with a file_name for raw bytes — one or the other, not both.\n\nRe-hosting is the recommended path even when you already have a URL. A scheduled post publishes hours or days after it is created, and an asset that has expired or moved by then publishes as a post with a broken attachment.","operationId":"uploadMedia","externalDocs":{"description":"Upload Media documentation","url":"https://www.linkedmash.com/api-docs/upload-media"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"url":{"type":"string","format":"uri","example":"https://example.com/assets/diagram.png","description":"Remote http(s) URL to re-host. Provide either url or file_base64."},"file_base64":{"type":"string","description":"Base64-encoded file bytes — an alternative to url."},"file_name":{"type":"string","description":"Original file name."},"mime_type":{"type":"string","example":"image/png","description":"MIME type of the file (e.g., 'image/png')."}}},"example":{"url":"https://example.com/assets/diagram.png","mime_type":"image/png"}}}},"responses":{"201":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["url","file_type","file_name","mime_type"],"properties":{"url":{"type":"string","format":"uri"},"file_type":{"type":"string"},"file_name":{"type":"string"},"mime_type":{"type":"string"}}}}},"example":{"status":true,"data":{"url":"https://media.linkedmash.com/uploads/9c1f0b2e/diagram.png","file_type":"image","file_name":"diagram.png","mime_type":"image/png"}}}}},"400":{"description":"Bad Request. Neither url nor file_base64 was given, the url was invalid or not http(s), the source could not be fetched, file_name was missing alongside file_base64, or the base64 payload could not be decoded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to upload media\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/posts/{id}/schedule":{"post":{"tags":["Drafts"],"summary":"Schedule Post","description":"Schedule a draft for publishing now, at the next open slot, or at a specific time. Requires a paid Creator or Lifetime plan.\n\nPOST /v1/posts/{id}/schedule takes an existing draft and either publishes it immediately or places it in the posting queue. publish_at drives the behaviour: 'now' publishes straight to LinkedIn, 'next-slot' resolves the next free slot from the account's posting schedule, and an ISO-8601 timestamp schedules that exact time.\n\ntimezone is an IANA name and is required for everything except 'now', because a wall-clock time without a zone is ambiguous. Media can be attached at schedule time with post_type, media_url and media_mime_type if it was not attached to the draft.","operationId":"schedulePost","externalDocs":{"description":"Schedule Post documentation","url":"https://www.linkedmash.com/api-docs/schedule-post"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The id of the draft to schedule.","schema":{"type":"string","example":"drf_8f3a21c9"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["publish_at"],"properties":{"publish_at":{"oneOf":[{"type":"string","enum":["now","next-slot"]},{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}","description":"ISO-8601 local or offset timestamp, interpreted with the timezone field."}],"example":"next-slot","description":"'now', 'next-slot', or an ISO-8601 timestamp."},"timezone":{"type":"string","example":"Europe/Berlin","description":"IANA timezone. Required unless publish_at is 'now'."},"post_type":{"type":"string","description":"Media type to attach: text, image, video, or pdf."},"media_url":{"type":"string","format":"uri","description":"Public URL of an image, video, or PDF to attach."},"media_mime_type":{"type":"string","description":"MIME type of the attached media (e.g., 'image/png')."}}},"example":{"publish_at":"next-slot","timezone":"Europe/Berlin"}}}},"responses":{"201":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["ok","scheduleId","runAtUTC"],"properties":{"ok":{"type":"boolean"},"scheduleId":{"type":"string"},"runAtUTC":{"type":"string","format":"date-time"}}}}},"example":{"status":true,"data":{"ok":true,"scheduleId":"sch_3a9f81d2","runAtUTC":"2026-06-24T08:30:00.000Z"}}}}},"400":{"description":"Bad Request. publish_at missing; timezone missing for a non-'now' publish; empty draft text on 'now'; or no free slot available for 'next-slot'.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"404":{"description":"Not Found. No draft with that id on this account.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"NOT_FOUND","error":"Draft not found."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to schedule post\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/queue":{"get":{"tags":["Queue"],"summary":"Get Queue","description":"List scheduled posts grouped by day, optionally filtered by status. Requires a paid Creator or Lifetime plan.\n\nGET /v1/queue returns the account's posting queue — the schedule entries for posts that are waiting to publish, and the ones that already have. Pass status to narrow to draft, scheduled or published. Each entry carries the scheduleId used by the cancel and reschedule routes.\n\nThis is the read you want for a calendar view or a 'what is going out this week' check, as distinct from GET /v1/posts, which lists the drafts themselves.","operationId":"getQueue","externalDocs":{"description":"Get Queue documentation","url":"https://www.linkedmash.com/api-docs/get-queue"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"Filter by status: draft, scheduled, or published.","schema":{"type":"string","example":"scheduled"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["date","entries"],"properties":{"date":{"type":"string","format":"date"},"entries":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","time","content","status","scheduledTimeUTC","timezone"],"properties":{"id":{"type":"string"},"time":{"type":"string"},"content":{"type":"string"},"status":{"type":"string"},"scheduledTimeUTC":{"type":"string","format":"date-time"},"timezone":{"type":"string"}}}}}}}}},"example":{"status":true,"data":[{"date":"2026-06-24","entries":[{"id":"sch_3a9f81d2","time":"8:30 am","content":"5 lessons from shipping every week for a year:","status":"scheduled","scheduledTimeUTC":"2026-06-24T08:30:00.000Z","timezone":"America/New_York"}]}]}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to list the queue\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/queue/slots":{"get":{"tags":["Queue"],"summary":"Get Posting Slots","description":"Get the next available posting slots from your schedule. Requires a paid Creator or Lifetime plan.\n\nGET /v1/queue/slots computes the next free posting times from the account's recurring schedule grid and returns them as concrete timestamps. count controls how many to return, and timezone is the IANA zone the times are expressed in.\n\nIt is the endpoint to call before scheduling if you want to show a user their options, or to pick a specific slot rather than letting POST /v1/posts/{id}/schedule resolve 'next-slot' for you.","operationId":"getPostingSlots","externalDocs":{"description":"Get Posting Slots documentation","url":"https://www.linkedmash.com/api-docs/get-posting-slots"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"count","in":"query","required":false,"description":"Number of upcoming slots to return.","schema":{"type":"integer","example":5}},{"name":"timezone","in":"query","required":false,"description":"IANA timezone for the returned slot times.","schema":{"type":"string","example":"Europe/Berlin"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["day","time","date","displayDate"],"properties":{"day":{"type":"string"},"time":{"type":"string"},"date":{"type":"string","format":"date"},"displayDate":{"type":"string"}}}}}},"example":{"status":true,"data":[{"day":"Mon","time":"8:30 am","date":"2026-06-22","displayDate":"Mon, Jun 22"},{"day":"Wed","time":"8:30 am","date":"2026-06-24","displayDate":"Wed, Jun 24"}]}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to fetch posting slots\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/queue/{scheduleId}":{"delete":{"tags":["Queue"],"summary":"Cancel Scheduled Post","description":"Cancel a scheduled post and return its draft to the unscheduled state. Requires a paid Creator or Lifetime plan.\n\nDELETE /v1/queue/{scheduleId} cancels a scheduled post. The queue entry is removed and the underlying draft returns to the unscheduled state — the text is not deleted, so the same draft can be scheduled again later.\n\nscheduleId is the id from the schedule response or from GET /v1/queue, not the draft id. Passing a draft id here will not match anything.","operationId":"cancelScheduledPost","externalDocs":{"description":"Cancel Scheduled Post documentation","url":"https://www.linkedmash.com/api-docs/cancel-scheduled-post"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"scheduleId","in":"path","required":true,"description":"The id of the scheduled entry to cancel.","schema":{"type":"string","example":"sch_3a9f81d2"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["id","cancelled"],"properties":{"id":{"type":"string"},"cancelled":{"type":"boolean"}}}}},"example":{"status":true,"data":{"id":"sch_3a9f81d2","cancelled":true}}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"404":{"description":"Not Found. No cancellable queue entry with that scheduleId on this account.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"NOT_FOUND","error":"Scheduled post not found."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to cancel the scheduled post\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/queue/{scheduleId}/reschedule":{"post":{"tags":["Queue"],"summary":"Reschedule Post","description":"Move a scheduled post to a new time or the next open slot. Requires a paid Creator or Lifetime plan.\n\nPOST /v1/queue/{scheduleId}/reschedule moves an already-scheduled post to a different time without cancelling and re-creating it. publish_at takes an ISO-8601 timestamp or the literal 'next-slot', and timezone is a required IANA zone in both cases.\n\nUnlike the schedule route, timezone is mandatory here even for 'next-slot', because slot resolution is done in the user's local grid and there is no 'now' shortcut to fall back on.","operationId":"reschedulePost","externalDocs":{"description":"Reschedule Post documentation","url":"https://www.linkedmash.com/api-docs/reschedule-post"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"scheduleId","in":"path","required":true,"description":"The id of the scheduled entry to reschedule.","schema":{"type":"string","example":"sch_3a9f81d2"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"publish_at":{"oneOf":[{"type":"string","enum":["next-slot"]},{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}","description":"ISO-8601 local or offset timestamp, interpreted with the timezone field."}],"example":"2026-08-12T08:30:00","description":"An ISO-8601 timestamp or 'next-slot'."},"timezone":{"type":"string","example":"Europe/Berlin","description":"IANA timezone for the new time."}}},"example":{"publish_at":"2026-08-12T08:30:00","timezone":"Europe/Berlin"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["ok","newRunAtUTC"],"properties":{"ok":{"type":"boolean"},"newRunAtUTC":{"type":"string","format":"date-time"}}}}},"example":{"status":true,"data":{"ok":true,"newRunAtUTC":"2026-06-26T08:30:00.000Z"}}}}},"400":{"description":"Bad Request. publish_at or timezone missing, or 'next-slot' with no free slot in the schedule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"404":{"description":"Not Found. No queue entry with that scheduleId on this account.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"NOT_FOUND","error":"Scheduled post not found."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to reschedule the post\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/schedule":{"get":{"tags":["Schedule"],"summary":"Get Posting Schedule","description":"Get your recurring posting schedule grid. Requires a paid Creator or Lifetime plan.\n\nGET /v1/schedule returns the recurring posting schedule: an IANA timezone and a grid of repeating time slots, each with the weekdays it applies to. This grid is what /v1/queue/slots turns into concrete timestamps and what 'next-slot' scheduling resolves against.\n\nAn account that has never set a schedule gets a default of { timezone: \"UTC\", grid: [] } rather than a 404, so you can read this safely before deciding whether to prompt a user to configure one.","operationId":"getPostingSchedule","externalDocs":{"description":"Get Posting Schedule documentation","url":"https://www.linkedmash.com/api-docs/get-posting-schedule"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["timezone","grid"],"properties":{"timezone":{"type":"string"},"grid":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["time","days"],"properties":{"time":{"type":"string"},"days":{"type":"object","additionalProperties":false,"required":["Mon","Wed","Fri"],"properties":{"Mon":{"type":"boolean"},"Wed":{"type":"boolean"},"Fri":{"type":"boolean"}}}}}}}}}},"example":{"status":true,"data":{"timezone":"America/New_York","grid":[{"time":"8:30 am","days":{"Mon":true,"Wed":true,"Fri":true}}]}}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to fetch the posting schedule\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"tags":["Schedule"],"summary":"Set Posting Schedule","description":"Replace your recurring posting schedule grid. Requires a paid Creator or Lifetime plan.\n\nPUT /v1/schedule replaces the recurring posting schedule. Both timezone (an IANA name, as a string) and grid (an array) are required, and the write is a full replacement — the stored schedule becomes exactly what you send.\n\nEach grid entry is a repeating slot: a wall-clock time plus the weekdays it applies to, for example { time: \"8:30 am\", days: { Mon: true, Wed: true, Fri: true } }. Together they define every candidate publishing time for 'next-slot' scheduling.","operationId":"setPostingSchedule","externalDocs":{"description":"Set Posting Schedule documentation","url":"https://www.linkedmash.com/api-docs/set-posting-schedule"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["timezone","grid"],"properties":{"timezone":{"type":"string","example":"America/New_York","description":"IANA timezone for the schedule."},"grid":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["time","days"],"properties":{"time":{"type":"string","description":"Local posting time, for example 8:30 am."},"days":{"type":"object","description":"Enabled weekdays keyed by their three-letter English abbreviation.","additionalProperties":{"type":"boolean"}}}},"example":[{"time":"8:30 am","days":{"Mon":true,"Wed":true,"Fri":true}}],"description":"The schedule grid as [{ time, days }]."}}},"example":{"timezone":"America/New_York","grid":[{"time":"8:30 am","days":{"Mon":true,"Wed":true,"Fri":true}}]}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["timezone","grid"],"properties":{"timezone":{"type":"string"},"grid":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["time","days"],"properties":{"time":{"type":"string"},"days":{"type":"object","additionalProperties":false,"required":["Mon","Wed","Fri"],"properties":{"Mon":{"type":"boolean"},"Wed":{"type":"boolean"},"Fri":{"type":"boolean"}}}}}}}}}},"example":{"status":true,"data":{"timezone":"America/New_York","grid":[{"time":"8:30 am","days":{"Mon":true,"Wed":true,"Fri":true}}]}}}}},"400":{"description":"Bad Request. timezone was missing or not a string, or grid was not an array.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to update the posting schedule\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/analytics":{"get":{"tags":["Analytics"],"summary":"Get Analytics","description":"Get aggregate account analytics over a date range. Requires a paid Creator or Lifetime plan.\n\nGET /v1/analytics returns account-level LinkedIn performance over a date range: impressions, reactions, comments and reshares as a metrics object, plus the current follower count. date_range takes a shorthand window such as 7d, 30d or 90d.\n\nThe numbers come from LinkedIn through the connected account, so they are only as complete as what LinkedIn exposes for that profile, and they reflect the connected account's own posts rather than anything in the saved-posts library.","operationId":"getAnalytics","externalDocs":{"description":"Get Analytics documentation","url":"https://www.linkedmash.com/api-docs/get-analytics"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"date_range","in":"query","required":false,"description":"Date range to summarize, e.g. 7d, 30d, or 90d.","schema":{"type":"string","example":"30d"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"object","additionalProperties":false,"required":["metrics","followers"],"properties":{"metrics":{"type":"object","additionalProperties":false,"required":["impressions","reactions","comments","reshares"],"properties":{"impressions":{"type":"integer"},"reactions":{"type":"integer"},"comments":{"type":"integer"},"reshares":{"type":"integer"}}},"followers":{"type":"integer"}}}}},"example":{"status":true,"data":{"metrics":{"impressions":48210,"reactions":1932,"comments":412,"reshares":188},"followers":12480}}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to fetch analytics\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/analytics/posts":{"get":{"tags":["Analytics"],"summary":"Get Post Analytics","description":"Get per-post analytics over a date range. Requires a paid Creator or Lifetime plan.\n\nGET /v1/analytics/posts returns per-post performance for recently published posts, over the window given by date_range, capped by limit. It is the breakdown behind the totals in GET /v1/analytics.\n\nUse it to rank your own posts by engagement, to feed a weekly report, or to close the loop on a scheduling workflow — publish through /v1/posts and read the outcome back here.","operationId":"getPostAnalytics","externalDocs":{"description":"Get Post Analytics documentation","url":"https://www.linkedmash.com/api-docs/get-post-analytics"},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"date_range","in":"query","required":false,"description":"Date range to summarize, e.g. 7d, 30d, or 90d.","schema":{"type":"string","example":"30d"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of posts to return.","schema":{"type":"integer","example":10}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","data"],"properties":{"status":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","text","impressions","engagements","likes","comments"],"properties":{"id":{"type":"string"},"text":{"type":"string"},"impressions":{"type":"integer"},"engagements":{"type":"integer"},"likes":{"type":"integer"},"comments":{"type":"integer"}}}}}},"example":{"status":true,"data":[{"id":"7336731872414035968","text":"5 lessons from shipping every week for a year:","impressions":18420,"engagements":742,"likes":531,"comments":96}]}}}},"401":{"description":"Unauthorized. 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.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"UNAUTHORIZED","error":"Unauthorized"}}}},"402":{"description":"Payment Required. Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","code","error"],"properties":{"status":{"type":"boolean"},"code":{"type":"string"},"error":{"type":"string"}}},"example":{"status":false,"code":"SUBSCRIPTION_REQUIRED","error":"The content API requires a Creator or Lifetime plan."}}}},"500":{"description":"Server Error. Something failed on our side. The body carries message \"Failed to fetch post analytics\". Retry once; if it persists the request is not the problem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"LinkedMash API key","description":"Pass a LinkedMash API key as `Authorization: Bearer <key>`."},"apiKeyHeader":{"type":"apiKey","in":"header","name":"linkedmash-api-key","description":"Alternative header for clients that cannot set a Bearer authorization header."}},"schemas":{"ErrorResponse":{"type":"object","description":"LinkedMash API error envelope.","required":["status"],"properties":{"status":{"type":"boolean","const":false},"code":{"type":"string","description":"Stable machine-readable error code."},"error":{"type":"string","description":"Human-readable error message."},"message":{"type":"string","description":"Human-readable error message used by legacy endpoints."}},"anyOf":[{"required":["error"]},{"required":["message"]}]}}}}