List Labels
List all labels for the authenticated user.
GET /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.
This 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.
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 "https://api.linkedmash.com/v1/labels" \
-H "Authorization: Bearer $LINKEDMASH_API_KEY"Header parameters
Your secret API key. Should be provided as a Bearer token.
Response
{
"status": true,
"data": [
{
"id": 871042907,
"label_name": "Motivation",
"metadata": {}
},
{
"id": 137703742,
"label_name": "Visuals",
"metadata": {}
},
{
"id": 586565281,
"label_name": "Learning",
"metadata": {}
}
]
}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.
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.
Every label on the account, or the first 20 on a free-tier key.
Label identifier. This is the label_id accepted by /v1/labels/add and /v1/labels/remove, and the safer way to reference a label than by name.
Display name. Passing an unrecognised name to /v1/labels/add creates a new label, so read this list before writing by name.
Presentation metadata such as colour. Empty for labels created through the API.
How many labels this response contains — which on a truncated free-tier response is 20, not the account total. meta.total_count carries the account total when the list was trimmed.
Present only when the list was truncated, as { limited: true, reason: "FREE_TIER_LIMIT" }.
Building a classification loop
Labels are how automated triage writes its conclusions back into LinkedMash. Reading them is always the first step.
Read the labels once, cache the ids
Fetch this list at the start of a run and build a name-to-id map. Every subsequent add or remove should use label_id, which cannot create a duplicate label by typo.
Fetch the posts to classify
Call GET /v1/bookmarks with a filter that narrows to the untriaged set — commonly is_unread_only=true, or bookmarked_from set to your last run.
Write conclusions in bulk
Group posts by the label you decided on and send one POST /v1/labels/add per label with the full post_ids array, rather than one request per post.
Check meta before trusting a short list
A free-tier key receives the first 20 labels. meta.subscription is how you detect that, and it matters because a name-to-id map built from a truncated list will start creating duplicates. Reading labels costs no agent credits.
Behaviour and limits
Free accounts see the first 20 labels only
Without an active subscription the list is truncated to 20 and meta.subscription is set to { limited: true, reason: "FREE_TIER_LIMIT" }. The response is still a 200, so check meta rather than assuming a short list means a small account. Repeated polling still counts toward the free daily API/MCP call quota (100 per UTC day).
meta.count is the returned count, not the total
On a truncated free response meta.count is 20 even when the account has more labels. meta.total_count is added alongside it when the list was trimmed, so the two together tell you how much you are not seeing.
No pagination
Labels are returned in one payload with no cursor. Accounts hold tens of labels, not thousands, so there is nothing to page.
Filtering posts by label uses tag, not label_id
GET /v1/bookmarks takes a tag parameter that matches on the label name. label_id is only used by the two label mutation endpoints.
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.