---
title: "Create a job"
method: POST
path: "/api/v0/jobs"
tags: ["Jobs"]
---

# Create a job

`POST /api/v0/jobs`

## Request

- Base URL: `https://www.getonbrd.com`
- URL: `https://www.getonbrd.com/api/v0/jobs`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/getonbrd/apis/get-on-board-api/docs/api/v0/jobs/post.ts> (a function with typed inputs; its response is checked against the schema)

### Remote modality and locations

`remote_modality` controls which location fields the Jobs API reads:

- `fully_remote`: do not send location fields. Regions, countries, and cities are cleared.
- `remote_local`: send `location_region_ids` and/or `location_country_ids` as slugs from `GET /api/v0/regions` and `GET /api/v0/countries`.
- `no_remote`, `hybrid`, `temporarily_remote`: send `location_city_ids` as numeric city IDs from `GET /api/v0/cities`.

Unknown or wrong identifier types resolve to empty locations and can return `422`.
`location_city_ids` uses city IDs, not city names, country slugs, or `tenant_city_ids`.

Typical job publishing flow: create the job with `POST /api/v0/jobs`, review validation errors if the response is `422`, then submit the saved draft with `POST /api/v0/jobs/{job_id}/submit` so Get on Board can moderate it before publication. Use `lang=en` while integrating if you want English validation messages.

### Posting on behalf of a client brand (company shells)

Partner accounts (typically ATS integrations posting for many client companies) can brand a job
as one of their **company shells** instead of their own account: send `company_shell_id` with the
shell's slug (from `GET /api/v0/company_shells`). Every public surface — job page, company profile
link, logo, feeds, and public API — then shows the client company's identity, while applications,
processes, and billing stay on your account. Omit the field for a normal job; on update, send `""`
to detach the shell. See the **Company shells** section to create and manage shells.

### Naming the final employer (recruiters and outsourcing companies)

Use `hiring_company` and `hiring_company_website` when you are recruiting or outsourcing on behalf
of a client, to name the company where the applicant will actually work. Once `hiring_company` is
given, `hiring_company_website` is required too. From 5 Oct 2026, a job that our review flags as
hiding the final employer is rejected with `obfuscated_company` unless your company holds a
Recruiter-or-higher subscription. Placeholder names ("confidential", "rubro") and your own company
name are rejected — name the real client.

## Headers

- `Authorization` string, required

## Request body

- object
  - `expand` string[]
  - `questions` string
  - `title` string, required
  - `description` string, required
  - `projects` string, required
  - `category_id` string, required
  - `min_salary` string, required
  - `max_salary` string, required
  - `modality_id` string, required
  - `seniority_id` string, required
  - `remote_modality` 'no_remote' | 'temporarily_remote' | 'remote_local' | 'fully_remote' | 'hybrid', required: Work-location policy. Determines which location ID fields are accepted.
  - `functions` string
  - `perks` string
  - `state` string
  - `location_region_ids` string[], nullable: For `remote_local` jobs only. Region slugs from `GET /api/v0/regions`.
  - `location_country_ids` string[], nullable: For `remote_local` jobs only. Country slugs from `GET /api/v0/countries`.
  - `location_city_ids` integer[], nullable: Required for `no_remote`, `hybrid`, and `temporarily_remote`. Numeric city IDs from `GET /api/v0/cities`.
  - `company_shell_id` string, nullable: Partner accounts only. Slug of one of your company shells (`GET /api/v0/company_shells`) to publicly brand this job as that client company. Omit for a normal job. On update, send `""` to detach the shell. `404` for an unknown or foreign slug; `422` if your account is not partner-enabled.
  - `hiring_company` string, nullable: Name of the client company where the applicant will actually work, when you recruit or outsource on behalf of a client. Requires `hiring_company_website`. Placeholder names ("confidential", "rubro") and your own company name are rejected with `422`.
  - `hiring_company_website` string, nullable: Website of the client company named in `hiring_company`. Required whenever `hiring_company` is sent; it must be a valid http(s) URL and not your own company's domain.
  - `hide_salary` boolean: Hide the salary range on public job pages. Full-time and internship jobs still need `min_salary` and `max_salary`. While `true`, responses return `min_salary` and `max_salary` as `null`, so send only the fields you change: a job read back from the API and sent again returns `422`. Get on Board resets it to `false` when your subscription is cancelled or the job is unlocked as a regular (non-subscriber) job. Not the same as `confidential`, which keeps the whole job out of public listings.
  - `cv_required` boolean: Require the candidate's CV file when applying. Only applied when the subscription permits requiring a CV (can_require_resume?). Otherwise silently ignored; the request still succeeds.
  - `linkedin_required` boolean: Require the candidate's LinkedIn profile URL when applying. Only applied when the subscription permits requiring a CV (can_require_resume?). Otherwise silently ignored; the request still succeeds.

## Response `200`

Creates a new job posting for the authenticated company.

- object
  - `data` object, required
    - `id` string, required
    - `type` string, required
    - `attributes` object, required
      - `title` string, required
      - `description_headline` unknown, required
      - `description` string, required
      - `projects` string, required
      - `functions_headline` unknown, required
      - `functions` string, required
      - `benefits_headline` unknown, required
      - `benefits` string, required
      - `desirable_headline` unknown, required
      - `desirable` string, required
      - `remote` boolean, required
      - `remote_modality` string, required
      - `remote_zone` unknown, required
      - `countries` string[], required
      - `lang` string, required
      - `rejected_reasons` object[], required: Job moderation reasons, meaningful when state is rejected or submitted after rejection. Published jobs may retain earlier reasons. Each item has one reason key with localized title and description. Legacy jobs may also contain retired keys: candidate, compensation_missing, other. Consumers should tolerate unknown keys. Private job responses and job.created/job.updated webhooks share this shape.
        - `anonymous_company` object
          - `title` string, required
          - `description` string, required
        - `bad_job` object
          - `title` string, required
          - `description` string, required
        - `contact_info` object
          - `title` string, required
          - `description` string, required
        - `desirable_required` object
          - `title` string, required
          - `description` string, required
        - `duplicate` object
          - `title` string, required
          - `description` string, required
        - `excess_requirements` object
          - `title` string, required
          - `description` string, required
        - `inconsistent_information` object
          - `title` string, required
          - `description` string, required
        - `information` object
          - `title` string, required
          - `description` string, required
        - `insufficient_project_info` object
          - `title` string, required
          - `description` string, required
        - `irrelevant_requirements` object
          - `title` string, required
          - `description` string, required
        - `list_required_as_desirable` object
          - `title` string, required
          - `description` string, required
        - `mismatch_title_description` object
          - `title` string, required
          - `description` string, required
        - `multiple_positions` object
          - `title` string, required
          - `description` string, required
        - `non_compliant_business_practices` object
          - `title` string, required
          - `description` string, required
        - `no_position_info` object
          - `title` string, required
          - `description` string, required
        - `no_requirements` object
          - `title` string, required
          - `description` string, required
        - `not_really_remote` object
          - `title` string, required
          - `description` string, required
        - `obfuscated_company` object
          - `title` string, required
          - `description` string, required
        - `off_topic` object
          - `title` string, required
          - `description` string, required
        - `seniority_mismatch` object
          - `title` string, required
          - `description` string, required
        - `specific_school_required` object
          - `title` string, required
          - `description` string, required
        - `spelling_grammar` object
          - `title` string, required
          - `description` string, required
        - `talent_pool` object
          - `title` string, required
          - `description` string, required
        - `too_vague` object
          - `title` string, required
          - `description` string, required
        - `unclear_functions` object
          - `title` string, required
          - `description` string, required
      - `category_name` string, required
      - `perks` string[], required
      - `min_salary` integer, nullable, required
      - `max_salary` integer, nullable, required
      - `published_at` integer, required
      - `response_time_in_days` object, required
        - `min` unknown, required
        - `max` unknown, required
      - `applications_count` integer, required
      - `location_regions` object, required
        - `data` object[], required
          - `id` string, required
          - `type` string, required
          - `attributes` object, required
            - `name` string, required
      - `location_tenants` object, required
        - `data` object[], required
          - `id` string, required
          - `type` string, required
          - `attributes` object, required
            - `name` string, required
      - `location_cities` object, required
        - `data` object[], required
          - `id` string, required
          - `type` string, required
          - `attributes` object, required
            - `name` string, required
            - `country` string, required
      - `modality` object, required
        - `data` object, required
          - `id` integer, required
          - `type` string, required
      - `seniority` object, required
        - `data` object, required
          - `id` integer, required
          - `type` string, required
      - `tags` object, required
        - `data` unknown[], required
          - unknown
      - `state` string, required
      - `deleted` boolean, required
      - `questions` object, required
        - `data` object[], required
          - `id` string, required
          - `type` string, required
          - `attributes` object
            - `slug` string, required
            - `title` string, required
            - `help_text` string, nullable, required
            - `kind` string, required
            - `language` string, nullable, required
            - `required` boolean, required
            - `multiple` boolean, required
            - `choices` object[], required
              - …
            - `score` integer, nullable, required
            - `hidden` boolean, required
            - `created_at` integer, required
            - `updated_at` integer, required
      - `location_countries` object, required
        - `data` object[], required
          - `id` string, required
          - `type` string, required
          - `attributes` object, required
            - `name` string, required
      - `submitted_at` integer, required
      - `created_at` integer, required
      - `updated_at` integer, required
      - `company_shell_id` string, nullable
      - `hide_salary` boolean
      - `hiring_company` string, nullable
      - `hiring_company_website` string, nullable
  - `meta` object
    - `warnings` object, required
      - `questions` object[], required
        - `code` string, required
        - `detail` string
        - `at_index` integer
        - `provided` string, nullable
        - `errors` object, nullable
          - `title` string[]
          - `choices` string[]
          - `base` string[]

## Other responses

- `401`: Creates a new job posting for the authenticated company.
- `404`: Creates a new job posting for the authenticated company.
- `422`: Creates a new job posting for the authenticated company.

---

[API](https://skmtc.dev/getonbrd/apis/get-on-board-api.md) - [All operations](https://skmtc.dev/getonbrd/apis/get-on-board-api/llms.txt) - [OpenAPI document](https://skmtc.dev/getonbrd/apis/get-on-board-api/revisions/f8405113049f?raw)
