Projects
A project is a named container for content inside a workspace — typically one personal-brand profile or one company page. Notes, posts, sources, and queue slots all attach to a project. The API exposes a paginated list of the workspace’s projects and a single-project read — both read-only; mutating projects (creation, archive, pause) is dashboard-only. For LinkedIn company pages specifically,GET /v1/company-pages
adds activation status, stored admin-token health, and follower counts
on top of the plain project rows.
GET /v1/projects
List the projects the authenticated workspace owns, ordered by creation
time descending.
Query parameters
Response
Semantics
Field types, nullability and thetype / typeLabel enums live in the
OpenAPI reference tab (Project). What the schema doesn’t tell you:
- There is no
urlfield. The LinkedIn identity lives onusername, and it is a bare slug, never a URL: the author handle for a personal brand or amplifier (resolving tohttps://www.linkedin.com/in/<username>) and the company vanity name for a company page (https://www.linkedin.com/company/<username>). It isnulluntil the project is connected. Build the link yourself; don’t split the value on/in/. nameis resolved, not raw: a connected project reports the name LinkedIn holds, falling back to the dashboard label.avatarUrlis a CDN URL,nullbefore the project connects.statusisACTIVEfor every project the API can return today — the column has exactly one value — andisActiveis derived from it. Both are here for forward-compatibility; treat an unknownstatusas active.AMPLIFIERis a livetypealongsidePERSONAL_BRANDandCOMPANY_PAGE, and shares the personal-brand projection.linkedInanswers whether Scripe can publish as this project right now — see the next section.
linkedIn — the publishing precondition
Every project row carries the answer to “can Scripe post as this account
right now, and if not, what has to happen”.
Branch on
canPublish or state, never on connectionStatus.
connectionStatus is the stored health cache written by whatever last
talked to LinkedIn. It reads CONNECTED for accounts holding no access
token at all, and UNKNOWN for accounts that were simply never
connected; state applies token presence first.
Reading a project never probes LinkedIn — this is stored health as of
lastValidatedAt. The live check runs inside the schedule and publish
pre-flights, where a write is about to happen.
A company page has no connection of its own: it publishes through the
personal account it was linked to, so its block — including
reconnectUrl — describes that account. null means the page was never
linked to one, which is itself the answer.
linkedIn cannot be repaired through this API. Reconnecting is an OAuth
flow a human performs in the dashboard; relay reconnectUrl rather than
retrying.
GET /v1/projects/{projectId}
Single project read. Returns the same shape as above, wrapped in a data
field for symmetry with future write endpoints.
Response
Errors
Cross-workspace isolation
Every project read is scoped by the API key’s workspace. A request forproj_<other-workspace> returns 404 not_found — never a 403, so
attackers cannot enumerate which project ids exist outside their
workspace.
The same isolation applies to the list endpoint: you only see your own
workspace’s projects, and the pagination cursor is bound to that filter.
You cannot inflate the result set by replaying another workspace’s
cursor — the embedded (createdAt, id) keyset is workspace-agnostic, so
it just no-ops against your own data.
What’s NOT here (yet)
- Filtering by status / type. The list returns all projects, regardless of status. Filter client-side.
- Project metrics. Engagement and analytics live on Analytics.
- Write endpoints. Creating, pausing, or archiving a project is dashboard-only.