---
title: "Create job post location"
method: POST
path: "/v3/job_post_locations"
tags: ["Job Post Locations"]
---

# Create job post location

`POST /v3/job_post_locations`

Attach a location to an existing `job_post`. The supplied `type` must match the parent job board's location configuration — boards set to `office` or `custom_list` reject `free_text` values, and a `custom_list` value must reference a `job_board_custom_locations` row on the same board as the post. Issue one POST per location to build out a multi-location post; there is no batch create. To replace an existing location, delete the row via `DELETE /v3/job_post_locations/{id}` and post the new one.

## Request body

- object
  - `job_post_id` integer, required — Id of the `job_post` to attach this location to. The post's parent job board must also allow the supplied `type` — boards configured for `office` or `custom_list` locations reject `free_text` values, and vice versa.
  - `type` 'free_text' | 'office' | 'custom_list', required — How the location is sourced. Drives how `value` is interpreted: `free_text` treats `value` as a literal location string, `office` resolves it to an organization office id, and `custom_list` resolves it to a `job_board_custom_locations` id. Must match the parent job board's configured location strategy.
  - `value` string, required — Location value, interpreted per `type`. For `free_text`, the candidate-facing string (e.g. `Remote (US)`). For `office`, the integer office id as a string. For `custom_list`, the integer `job_board_custom_locations` id as a string — and the custom location must belong to the same job board as the post.

## Response `201`

Successful

- object
  - `id` integer
  - `created_at` string, date-time
  - `updated_at` string, date-time
  - `plain_text_location` string, nullable — Free-text location string shown on the job post (e.g. `New York, NY`, `Remote (US)`). Populated when `type` is `free_text`; `null` for `office` and `custom_list` rows, where the displayable text is resolved from the linked `office` or `job_board_custom_location` instead.
  - `office_id` integer, nullable — Id of the organization office this location resolves to. Populated when `type` is `office`; `null` otherwise. Cross-reference with `/v3/offices` to fetch the office name and address.
  - `type` 'free_text' | 'office' | 'custom_list', nullable — How this location is sourced. `free_text` is an admin-typed string in `plain_text_location`; `office` references an organization office via `office_id`; `custom_list` references a board-scoped custom location via `custom_location_id`. Drives which of the three id/text fields is populated and is set by the parent job board's location configuration.
  - `job_post_id` integer, nullable — Id of the `job_post` this location is attached to. A single post can have multiple `job_post_locations` rows — one per location it's published in (e.g. `San Francisco`, `Remote (US)`, `New York` on one multi-location post).
  - `custom_location_id` integer, nullable — Id of the `job_board_custom_locations` row this location resolves to. Populated when `type` is `custom_list`; `null` otherwise. Custom locations are board-scoped — confirm the parent post lives on the same `job_board_id` before reusing an id.

## Other responses

- `401` — Unauthorized
- `403` — Forbidden
- `422` — Unprocessable Content

---

[API](https://skmtc.dev/greenhouse/apis/auth-api.md) · [All operations](https://skmtc.dev/greenhouse/apis/auth-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/greenhouse/auth-api/revisions/9517a2e54640/schema)
