---
title: "Get public project details"
method: GET
path: "/api/v1/public/{agencyId}/projects/{id}"
tags: ["Jobs Portal"]
---

# Get public project details

`GET /api/v1/public/{agencyId}/projects/{id}`

## Request

- Base URL: `https://api.recruitwithatlas.com`
- URL: `https://api.recruitwithatlas.com/api/v1/public/{agencyId}/projects/{id}`
- Auth: none declared
- TypeScript: <https://skmtc.dev/recruitwithatlas/apis/atlas-api/docs/api/v1/public/:agencyId/projects/:id/get.ts> (a function with typed inputs; its response is checked against the schema)

Use this endpoint to retrieve details of a public project without authentication.

This endpoint is limited to projects where `public` is `true`. It is intended for use in public-facing integrations such as career pages or job boards.

The response includes the `owner` — the lead consultant on the role, as `{ name, email }` — so you can display a contact on the job page. `owner.email` is `null` unless your agency has opted in to publishing project owners' emails. `owner` is `null` when the project has no owner, or when the recorded owner does not belong to the project's agency.

Compared to the authenticated **Get project details** endpoint, this response does not include `company`, `endClient`, `members`, or `stages`.

**What you need to provide:**
- The **agency ID** in the URL path - the agency the project belongs to
- The **project ID** in the URL path - the project you want to retrieve

Both IDs are UUIDs. If the project does not exist, does not belong to the specified agency, or is not marked as public, a 404 response is returned.

## Path parameters

- `agencyId` string, uuid, required: Agency ID
- `id` string, uuid, required: Project ID

## Response `200`

Public project details

- object
  - `status` 'ok', required
  - `data` object, required
    - `id` string, uuid, required
    - `jobRole` string, required: Job role/title
    - `jobNumber` string, nullable, required: Job reference number
    - `state` 'active' | 'closed' | 'on_hold' | 'talent_pool' | 'lead' | 'pitch' | 'opportunity', required: Project state
    - `jobDescription` string, nullable, required: Plain text job description
    - `jobDescriptionFormatted` string, nullable, required: Job description in formatted HTML
    - `contractType` 'full_time' | 'part_time' | 'contract' | 'non_exec' | 'null', nullable, required: Contract type
    - `workMode` 'office' | 'hybrid' | 'remote' | 'null', nullable, required: Work mode
    - `seniority` 'partner' | 'board' | 'founder' | 'cxo' | 'vp' | 'director' | 'manager' | 'senior' | 'middle' | 'junior' | 'null', nullable, required: Seniority level
    - `func` string, nullable, required: Job function
    - `hireTarget` integer, nullable, required: Target number of hires
    - `visaSupport` boolean, nullable, required: Whether visa support is offered
    - `salary` string, nullable, required: Salary or salary range
    - `salaryCurrency` string, nullable, required: Salary currency code
    - `location` object, nullable, required: Project location
      - `city` string, nullable, required: City/locality
      - `region` string, nullable, required: Region/state
      - `country` string, nullable, required: Country
      - `formattedAddress` string, nullable, required: Full formatted address
    - `customAttributes` object[], required: Custom attribute values for this project
      - `attributeId` string, uuid, required: Custom attribute definition ID
      - `attributeName` string, nullable, required: Attribute name
      - `attributeType` 'options' | 'text_block' | 'text_line' | 'number_input' | 'integer' | 'date' | 'null', nullable, required: Attribute type — drives the shape of each entry in `values`.
      - `values` union[], required: All values recorded for this attribute. For single-value attributes the array has one entry; for multi-select `options` attributes it may have several.
        - union: A single value entry. Shape depends on `attributeType`: - `text_line` / `text_block` → string - `integer` / `number_input` → number - `date` → ISO `YYYY-MM-DD` string - `options` → `{ optionId, optionValue }` object
          - string
          - number
          - object
            - `optionId` string, uuid, required: Selected option ID
            - `optionValue` string, nullable, required: Display value of the option
    - `createdAt` string, nullable, required: ISO 8601 creation date
    - `startedAt` string, nullable, required: Start date (YYYY-MM-DD)
    - `owner` object, nullable, required: Project owner (lead consultant), or null when the project has no owner or the recorded owner does not belong to the project's agency
      - `name` string, required: Owner name
      - `email` string, nullable, required: Owner email. `null` unless the agency has opted in to publishing project owners' emails
    - `updatedAt` string, nullable, required: ISO 8601 timestamp of the project's last modification. Persist the largest value seen across a response as the next sync cursor for `updatedAfter`.

## Other responses

- `404`: Project not found or not public
- `422`: Validation error - the request failed schema validation (`errors.fieldErrors`) or a business rule (`errors.formErrors`)
- `429`: Too many requests - the caller has exceeded the per-agency rate limit for the tier this endpoint counts against (default per minute: 1200 read / 400 write / 60 upload). Inspect the `RateLimit-*` headers — returned on every response, not only on 429s — and back off until the window resets. See the "Rate limits" section of the introduction for details.
- `500`: Internal server error

## Changes

- **2026-11-03** `158ee454751c`: 2 breaking, 4 warning
  - the response property `data/owner/email` became nullable for the status `200`
  - removed the required property `data/owner/userId` from the response with the `200` status
  - added the new `undefined` enum value to the `data/contractType` response property for the response status `200`
  - added the new `undefined` enum value to the `data/customAttributes/items/attributeType` response property for the response status `200`
  - …2 more
- **2026-10-03** `cd4bc8bbd95e`: 1 info
  - added the optional property `error` to the response with the `422` status

[Operation history](https://skmtc.dev/recruitwithatlas/apis/atlas-api/changes/api/v1/public/:agencyId/projects/:id/get.md)

---

[API](https://skmtc.dev/recruitwithatlas/apis/atlas-api.md) - [All operations](https://skmtc.dev/recruitwithatlas/apis/atlas-api/llms.txt) - [OpenAPI document](https://skmtc.dev/recruitwithatlas/apis/atlas-api/revisions/158ee454751c?raw)
