> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pubrio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 채용 공고 검색

> 회사, 직책, 직무, 직급, 국가, 게시일로 열린 채용 공고를 찾고, Pubrio가 모든 공고에 추가하는 분류를 읽습니다.

[채용 공고 검색](/ko/api-reference/endpoint/companies/job_search)은 Pubrio가 수집한 열린 채용 공고를 공고당 한 행으로 반환하며, 각 행은 공고를 게시한 회사에 연결됩니다. 모든 행에는 원본 공고(직책, 위치, URL, 게시자 날짜)와 함께 Pubrio가 직책에서 도출한 세 필드 `functions`, `seniority_rank`, `location_id`가 있습니다.

```bash theme={null}
curl -X POST https://api.pubrio.com/companies/jobs/search \
  -H "pubrio-api-key: $PUBRIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domains": ["stripe.com"],
    "seniority_ranks": [4, 5],
    "launch_dates": ["2026-08-01", "2026-08-31"],
    "per_page": 25
  }'
```

## 언제 사용하나

* **한 계정의 채용 시그널** — 회사를 전달하고 무엇을, 어디서, 어떤 레벨로 채용하는지 읽습니다.
* **역할 기반 프로스펙팅** — 한 국가에서 시니어 엔지니어링이나 영업 역할을 여는 회사를 찾은 뒤, 각 행의 `domain_search_id`로 [인물 검색](/ko/api-reference/endpoint/people/search)으로 넘어갑니다.
* **증분 동기화** — 저장해 둔 최신 수집 시각을 `created_at`에 설정해 폴링합니다.

행이 아니라 집계가 필요하면 [채용 인사이트](/ko/api-reference/endpoint/companies/job_insights)를 사용하세요. 회사가 공고를 올릴 때 알림을 받고 싶다면 `signal_types: ["jobs"]`로 [모니터](/ko/developer-guides/examples/tracking-job-postings)를 만드세요.

## 회사로 범위 지정

가장 빠른 검색은 회사를 지정하는 것입니다. 세 식별자 모두 같은 레코드로 해석되며 섞어 쓸 수 있습니다:

| 키               | 값                                             | 비고                                                 |
| --------------- | --------------------------------------------- | -------------------------------------------------- |
| `domains`       | `["stripe.com"]`                              | `https://www.stripe.com/jobs` 같은 URL은 도메인으로 정규화됩니다 |
| `linkedin_urls` | `["https://www.linkedin.com/company/stripe"]` | 회사 페이지만                                            |
| `companies`     | `["5378845d-7726-4817-aba9-ced8c5f41dee"]`    | 이전 응답의 `domain_search_id`                          |

회사 없는 검색도 허용됩니다 — `{"locations": ["SG"], "seniority_ranks": [5]}`는 동작합니다 — 하지만 전체 인덱스를 대상으로 카운트합니다. 그러면 `total_entries`는 추정치이며, 매우 광범위한 필터에서는 `is_timeout`이 `true`일 수 있습니다.

## 필터

### 텍스트

| 키              | 타입         | 일치 대상                                                                            |
| -------------- | ---------- | -------------------------------------------------------------------------------- |
| `titles`       | `string[]` | 직책명. 단어 단위 매칭이므로 `["engineer"]`는 `Senior Software Engineer`도 반환합니다. 나열한 직책 중 하나. |
| `search_term`  | `string`   | 공고 제목에 대한 자유 텍스트.                                                                |
| `search_terms` | `string[]` | 여러 자유 텍스트 용어. 하나만 일치해도 됩니다.                                                      |

### 분류

| 키                 | 타입          | 일치 대상                                                                                                                                       |
| ----------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `functions`       | `string[]`  | 직책에서 도출한 직무 슬러그: `engineering`, `sales`, `marketing`, `finance`, `product_management` 등. 나열한 슬러그 중 하나. [직무](/ko/api-reference/enums#직무) 참고. |
| `seniority_ranks` | `integer[]` | `1` 주니어 · `2` 시니어 · `3` 매니저 · `4` 디렉터 · `5` 임원. [직급 계층](/ko/api-reference/enums#직급-계층) 참고.                                                  |

<Warning>
  둘은 잘못된 입력에 다르게 반응합니다. 알 수 없는 `functions` 슬러그는 **0**행을 반환합니다. 1–5 범위 밖의 `seniority_ranks` 값은 **무시**되어 모든 행을 반환합니다. 둘 다 오류를 내지 않습니다.
</Warning>

### 날짜

| 키              | 타입              | 일치 대상                                                                                                     |
| -------------- | --------------- | --------------------------------------------------------------------------------------------------------- |
| `launch_dates` | `[from, to]`    | 공고의 게시일 — 게시자가 `posting_date`를 주면 그 값, 아니면 Pubrio가 처음 본 날. UTC 날짜 경계이며 채용 인사이트와 일치하므로 **기본으로 이것을 사용하세요.** |
| `posted_dates` | `[from, to]`    | `posting_date`만. 날짜 경계는 워크스페이스 시간대를 따릅니다.                                                                 |
| `created_at`   | 날짜 또는 ISO 타임스탬프 | 이 시각 이후에 수집됨(UTC). 증분 폴링에서는 저장한 최신 행의 정확한 `created_at`을 전달하세요.                                            |

두 범위 모두 양끝 포함입니다. `launch_dates`에 요소 하나만 주면 그 하루와 일치합니다.

### 위치

| 키                   | 타입          | 일치 대상                                                                                                                                |
| ------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `locations`         | `string[]`  | 공고 국가, ISO alpha-2.                                                                                                                  |
| `exclude_locations` | `string[]`  | 제외할 공고 국가.                                                                                                                           |
| `location_ids`      | `integer[]` | Pubrio `location_id`로 지정한 공고 국가. [Locations](/ko/api-reference/endpoint/locations/locations) 엔드포인트와 각 행의 `location_id`가 갖는 숫자와 같습니다. |
| `company_locations` | `string[]`  | **회사 본사** 국가로, 공고 위치와 다를 수 있습니다.                                                                                                     |

### 페이징과 정렬

| 키                    | 기본값     | 비고                                                           |
| -------------------- | ------- | ------------------------------------------------------------ |
| `per_page`           | 25      | 플랜의 `max_search_per_page`로 제한.                               |
| `page`               | 1       | `max_search_page`로 제한. 응답의 `total_display_pages`가 상한을 알려줍니다. |
| `is_ascending_order` | `false` | 행은 `created_at` 최신순. `true`면 오래된 순.                          |

## 행의 모습

```json theme={null}
{
  "job_id": "4418496a-6a4f-4432-8910-50153e9ba27c",
  "job_search_id": "4418496a-6a4f-4432-8910-50153e9ba27c",
  "created_at": "2026-08-30T00:02:52.531Z",
  "last_modified": "2026-09-01T16:08:09.324Z",
  "title": "Finance and Strategy Partner",
  "job_url": "https://www.linkedin.com/jobs/view/4460586030",
  "location": "United States",
  "location_id": 357,
  "country": "United States",
  "country_code": "US",
  "posting_date": "2026-08-29",
  "source_type": "linkedin",
  "functions": ["consulting"],
  "seniority_rank": 5,
  "base_salary": null,
  "experience_requirement": null,
  "education_requirement": null,
  "employment_type": null,
  "companies": {
    "domain_search_id": "5378845d-7726-4817-aba9-ced8c5f41dee",
    "company_name": "Stripe",
    "linkedin_name": "stripe",
    "country_code": "US",
    "company_url": "https://stripe.com/",
    "domain": "stripe.com",
    "logo_url": "https://buckets.pubrio.com/company-logo/....jpg"
  }
}
```

* 직책을 분류할 수 없으면 `functions`는 `null`, `seniority_rank`는 `0`입니다. 그래도 필터를 쓰면 됩니다 — 미분류 행은 그저 일치하지 않을 뿐입니다.
* `posting_date`는 게시자의 날짜이고, `created_at`은 Pubrio가 공고를 처음 본 시각이며 기본 정렬 키입니다.
* `job_id`와 `job_search_id`는 같은 값이며, 어느 것이든 [채용 조회](/ko/api-reference/endpoint/companies/job_lookup)에 전달할 수 있습니다.

### 결과를 신뢰하기 전에 `metadata`를 읽으세요

```json theme={null}
"metadata": {
  "profile": null,
  "filters": { "domains": ["stripe.com"], "seniority_ranks": [4, 5], "per_page": 25, "language": "en" },
  "ignored_fields": []
}
```

`ignored_fields`는 엔드포인트가 인식하지 못한 본문 키를 나열합니다. `"seniorty_ranks"` 같은 오타는 요청을 실패시키지 않고 조용히 검색 범위를 넓힙니다. 자동화된 모든 곳에서 이 배열이 비어 있는지 확인하세요.

## 레시피

<Tabs>
  <Tab title="최근 30일 시니어 엔지니어링 채용">
    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.pubrio.com/companies/jobs/search \
        -H "pubrio-api-key: $PUBRIO_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "domains": ["stripe.com", "adyen.com", "checkout.com"],
          "functions": ["engineering", "data_science"],
          "seniority_ranks": [3, 4, 5],
          "launch_dates": ["2026-08-05", "2026-09-04"],
          "per_page": 25
        }'
      ```

      ```python Python theme={null}
      import os, requests

      r = requests.post(
          "https://api.pubrio.com/companies/jobs/search",
          headers={"pubrio-api-key": os.environ["PUBRIO_API_KEY"], "Content-Type": "application/json"},
          json={
              "domains": ["stripe.com", "adyen.com", "checkout.com"],
              "functions": ["engineering", "data_science"],
              "seniority_ranks": [3, 4, 5],
              "launch_dates": ["2026-08-05", "2026-09-04"],
              "per_page": 25,
          },
      )
      body = r.json()
      assert body["metadata"]["ignored_fields"] == []
      for job in body["data"]["jobs"]:
          print(job["companies"]["company_name"], "-", job["title"], job["seniority_rank"])
      ```
    </CodeGroup>
  </Tab>

  <Tab title="싱가포르에서 영업 리더를 채용 중인 곳">
    ```bash cURL theme={null}
    curl -X POST https://api.pubrio.com/companies/jobs/search \
      -H "pubrio-api-key: $PUBRIO_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "locations": ["SG"],
        "functions": ["sales", "business_development"],
        "seniority_ranks": [4, 5],
        "launch_dates": ["2026-08-01", "2026-09-04"],
        "per_page": 25
      }'
    ```

    행을 `companies.domain_search_id`로 그룹화하세요 — 서로 다른 회사 각각이 잠재 고객이며, 그 id는 [인물 검색](/ko/api-reference/endpoint/people/search)의 `companies`에 바로 들어갑니다.
  </Tab>

  <Tab title="증분 동기화">
    ```python Python theme={null}
    import os, requests

    API = "https://api.pubrio.com/companies/jobs/search"
    HEADERS = {"pubrio-api-key": os.environ["PUBRIO_API_KEY"]}

    def sync(domains, since):
        """`since`(ISO 타임스탬프) 이후에 수집된 모든 공고를 가져오고 새 커서를 반환합니다."""
        newest = since
        page = 1
        while True:
            body = requests.post(API, headers=HEADERS, json={
                "domains": domains, "created_at": since, "page": page, "per_page": 25,
            }).json()
            rows = body["data"]["jobs"]
            if not rows:
                break
            for job in rows:  # 최신순
                newest = max(newest, job["created_at"])
                print(job["job_id"], job["title"])  # 여기서 저장소에 upsert
            if page >= body["data"]["pagination"]["total_display_pages"]:
                break
            page += 1
        return newest

    cursor = sync(["stripe.com"], "2026-09-01T00:00:00Z")
    # `cursor`를 저장하고 다음 실행에서 `since`로 전달하세요
    ```

    커서는 저장한 최신 행의 전체 `created_at`이므로 다음 실행에서는 그 한 행만 다시 전달됩니다. `job_id`로 upsert하세요. 행은 최신순으로 도착하므로 바쁜 날에도 커서가 플랜의 페이지 상한을 넘지 않습니다.
  </Tab>
</Tabs>

## 관련

<CardGroup cols={2}>
  <Card title="채용 공고 검색 레퍼런스" icon="code" href="/ko/api-reference/endpoint/companies/job_search">
    모든 파라미터와 응답 필드.
  </Card>

  <Card title="채용 인사이트" icon="chart-column" href="/ko/api-reference/endpoint/companies/job_insights">
    한 회사의 직무, 직급, 국가, 주별 카운트.
  </Card>

  <Card title="열거값 및 상수" icon="list" href="/ko/api-reference/enums">
    직급 계층과 전체 직무 어휘.
  </Card>

  <Card title="모니터로 채용 공고 추적" icon="bell" href="/ko/developer-guides/examples/tracking-job-postings">
    폴링 대신 웹훅을 받으세요.
  </Card>
</CardGroup>
