---
title: "Get Public Role"
method: GET
path: "/api/public/roles/{role_id}"
tags: ["roles"]
---

# Get Public Role

`GET /api/public/roles/{role_id}`

## Request

- Base URL: `https://api.parlel.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.parlel.com/api/public/roles/{role_id}`
- Auth: none declared

One role, readable while it is open AND after it is closed.

## The rule this endpoint exists to keep

A closed role still resolves here. Links to it exist in messages, in
newsletters, in saved tabs, and in agent findings that cited it as evidence --
and an agent's citation that 404s is worse than useless, because it makes the
finding look fabricated. So closing removes a role from the board and from
matching, and changes nothing at all about whether this URL works. The
response says ``status: "closed"`` and carries ``closed_at``, which is what
lets a reader see the truth: this was real, and it is over.

404 in exactly two cases, and both are about something that was never public:
a draft, and a role whose company page is private. One answer for both, plus
for an id that does not exist, so this cannot be used to discover that a
company is quietly staging openings.

Anonymous, like the board. A shared link is followed by strangers, by crawlers
and by expired sessions, and none of those may see a 401. It takes no viewer at
all, not even an optional one: there is no owner-preview case to serve, because
a draft 404s here for its own author too (the owner's view of a draft is
``GET /api/roles/{id}``), so resolving a viewer could only ever change the view
counter and never the body -- which is what keeps this response identical for
everyone and therefore shared-cacheable.

The consequence, and it is a real one: unlike the company page, **a company's
own visits to its role page are counted.** The mitigation is that managing
roles does not go through here -- ``GET /api/roles`` and the editor never touch
the counter -- so inflating it takes deliberately opening the public page.

The view counter uses the same targeted UPDATE as
``companies.get_public_company`` -- atomic, so two concurrent readers cannot
each read 7 and each write 8 -- and the commit expires the loaded rows, which
is why the skills are read after it rather than before.

## Path parameters

- `role_id` string, required

## Response `200`

Successful Response

- object

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/parlel/apis/parlel-api.md) · [All operations](https://skmtc.dev/parlel/apis/parlel-api/llms.txt) · [OpenAPI document](https://skmtc.dev/parlel/apis/parlel-api/revisions/4d41a8f5cfc9?raw)
