> ## 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.

# Recherche d'offres d'emploi

> Trouvez des offres d'emploi ouvertes par entreprise, intitulé, fonction, séniorité, pays et date de publication — et consultez la classification que Pubrio ajoute à chaque offre.

[Job Search](/fr/api-reference/endpoint/companies/job_search) renvoie les offres d'emploi ouvertes que Pubrio a capturées, une ligne par offre, chacune liée à l'entreprise qui l'a publiée. Chaque ligne contient l'offre brute (intitulé, lieu, URL, date de publication) ainsi que trois champs que Pubrio déduit de l'intitulé : `functions`, `seniority_rank` et `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
  }'
```

## Quand l'utiliser

* **Signaux de recrutement pour un compte donné** — indiquez l'entreprise et consultez ce qu'elle recrute, où et à quel niveau.
* **Prospection par rôle** — recherchez dans un pays les entreprises qui ouvrent des postes seniors en ingénierie ou en vente, puis passez à [People Search](/fr/api-reference/endpoint/people/search) avec le `domain_search_id` de chaque ligne.
* **Synchronisation incrémentale** — interrogez avec `created_at` défini sur l'heure d'ingestion la plus récente que vous avez stockée.

Si vous souhaitez un total courant plutôt que des lignes, utilisez [Job Insights](/fr/api-reference/endpoint/companies/job_insights). Si vous souhaitez être averti lorsqu'une entreprise publie une offre, créez un [Monitor](/fr/developer-guides/examples/tracking-job-postings) avec `signal_types: ["jobs"]`.

## Cibler une entreprise

Les recherches les plus rapides nomment l'entreprise. Les trois identifiants pointent vers la même fiche et peuvent être combinés :

| Clé             | Valeur                                        | Remarques                                                                         |
| --------------- | --------------------------------------------- | --------------------------------------------------------------------------------- |
| `domains`       | `["stripe.com"]`                              | Les URL telles que `https://www.stripe.com/jobs` sont normalisées vers le domaine |
| `linkedin_urls` | `["https://www.linkedin.com/company/stripe"]` | Pages entreprise uniquement                                                       |
| `companies`     | `["5378845d-7726-4817-aba9-ced8c5f41dee"]`    | `domain_search_id` provenant d'une réponse antérieure                             |

Les recherches sans entreprise sont autorisées — `{"locations": ["SG"], "seniority_ranks": [5]}` fonctionne — mais elles pèsent sur l'index entier. `total_entries` devient alors une estimation, et `is_timeout` peut valoir `true` sur des filtres très larges.

## Filtres

### Texte

| Clé            | Type       | Correspond à                                                                                                                                              |
| -------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `titles`       | `string[]` | Intitulés de poste. Correspondance au niveau du mot, donc `["engineer"]` renvoie aussi `Senior Software Engineer`. N'importe lequel des intitulés listés. |
| `search_term`  | `string`   | Texte libre recherché dans l'intitulé de l'offre.                                                                                                         |
| `search_terms` | `string[]` | Plusieurs termes en texte libre, dont l'un au moins peut correspondre.                                                                                    |

### Classification

| Clé               | Type        | Correspond à                                                                                                                                                                                                           |
| ----------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `functions`       | `string[]`  | Slugs de fonction déduits de l'intitulé : `engineering`, `sales`, `marketing`, `finance`, `product_management`, … N'importe lequel des slugs listés. Voir [Fonctions de poste](/fr/api-reference/enums#job-functions). |
| `seniority_ranks` | `integer[]` | `1` junior · `2` senior · `3` manager · `4` directeur · `5` exécutif. Voir [Rangs de séniorité](/fr/api-reference/enums#seniority-ranks).                                                                              |

<Warning>
  Les deux se comportent différemment face à une entrée invalide. Un slug `functions` inconnu renvoie **zéro** ligne. Une valeur `seniority_ranks` en dehors de 1–5 est **ignorée** et renvoie toutes les lignes. Aucun des deux ne génère d'erreur.
</Warning>

### Dates

| Clé            | Type                   | Correspond à                                                                                                                                                                                                                      |
| -------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `launch_dates` | `[from, to]`           | La date de lancement de l'offre — `posting_date` lorsque l'éditeur en fournit une, sinon le jour où Pubrio l'a vue pour la première fois. Limites de journée en UTC ; cohérent avec Job Insights, donc **à utiliser par défaut.** |
| `posted_dates` | `[from, to]`           | `posting_date` uniquement. Les limites de journée suivent le fuseau horaire de votre espace de travail.                                                                                                                           |
| `created_at`   | date ou horodatage ISO | Ingéré à partir de cet instant (UTC). Passez le `created_at` exact de votre ligne stockée la plus récente pour une interrogation incrémentale.                                                                                    |

Les deux périodes sont inclusives. `launch_dates` avec un seul élément correspond à cette journée précise.

### Lieu

| Clé                 | Type        | Correspond à                                                                                                                                                                             |
| ------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `locations`         | `string[]`  | Pays de l'offre, ISO alpha-2.                                                                                                                                                            |
| `exclude_locations` | `string[]`  | Pays de l'offre à exclure.                                                                                                                                                               |
| `location_ids`      | `integer[]` | Pays de l'offre par `location_id` Pubrio, les mêmes numéros que porte le endpoint [Locations](/fr/api-reference/endpoint/locations/locations) et le champ `location_id` de chaque ligne. |
| `company_locations` | `string[]`  | Pays du **siège social de l'entreprise**, qui peut différer du lieu du poste.                                                                                                            |

### Pagination et ordre

| Clé                  | Par défaut | Remarques                                                                                                                            |
| -------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `per_page`           | 25         | Plafonné par le `max_search_per_page` de votre offre.                                                                                |
| `page`               | 1          | Plafonné par `max_search_page` ; le `total_display_pages` de la réponse indique le plafond.                                          |
| `is_ascending_order` | `false`    | Les lignes sont ordonnées par `created_at`, les plus récentes en premier. `true` inverse l'ordre vers les plus anciennes en premier. |

## À quoi ressemble une ligne

```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` vaut `null` et `seniority_rank` vaut `0` lorsque l'intitulé n'a pas pu être classifié. Filtrez tout de même sur ces champs — les lignes non classifiées ne correspondent simplement pas.
* `posting_date` est la date de l'éditeur ; `created_at` est le moment où Pubrio a vu l'offre pour la première fois, et sert de clé de tri par défaut.
* `job_id` et `job_search_id` ont la même valeur ; passez l'un ou l'autre à [Job Lookup](/fr/api-reference/endpoint/companies/job_lookup).

### Lisez `metadata` avant de faire confiance à un résultat

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

`ignored_fields` liste toute clé du corps de la requête que le endpoint n'a pas reconnue. Une faute de frappe comme `"seniorty_ranks"` ne fait pas échouer la requête — elle l'élargit silencieusement. Vérifiez que ce tableau est vide dans tout ce qui est automatisé.

## Recettes

<Tabs>
  <Tab title="Recrutements seniors en ingénierie, 30 derniers jours">
    <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="Qui recrute des leaders commerciaux à Singapour">
    ```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
      }'
    ```

    Regroupez les lignes par `companies.domain_search_id` — chaque entreprise distincte est un prospect, et l'identifiant va directement dans `companies` sur [People Search](/fr/api-reference/endpoint/people/search).
  </Tab>

  <Tab title="Synchronisation incrémentale">
    ```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):
        """Fetch every posting ingested at or after `since` (ISO timestamp). Returns the new cursor."""
        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 first
                newest = max(newest, job["created_at"])
                print(job["job_id"], job["title"])  # upsert into your store here
            if page >= body["data"]["pagination"]["total_display_pages"]:
                break
            page += 1
        return newest

    cursor = sync(["stripe.com"], "2026-09-01T00:00:00Z")
    # persist `cursor` and pass it as `since` on the next run
    ```

    Le curseur est le `created_at` complet de la ligne la plus récente que vous avez stockée, si bien que seule cette ligne est redélivrée lors de l'exécution suivante. Effectuez un upsert sur `job_id`. Les lignes arrivent des plus récentes aux plus anciennes, si bien qu'une journée chargée ne pousse jamais le curseur au-delà du plafond de pages de votre offre.
  </Tab>
</Tabs>

## Voir aussi

<CardGroup cols={2}>
  <Card title="Référence Job Search" icon="code" href="/fr/api-reference/endpoint/companies/job_search">
    Tous les paramètres et champs de réponse.
  </Card>

  <Card title="Job Insights" icon="chart-column" href="/fr/api-reference/endpoint/companies/job_insights">
    Comptages par fonction, séniorité, pays et semaine pour une entreprise.
  </Card>

  <Card title="Énumérations et constantes" icon="list" href="/fr/api-reference/enums">
    Rangs de séniorité et vocabulaire complet des fonctions de poste.
  </Card>

  <Card title="Suivi des offres d'emploi avec les Monitors" icon="bell" href="/fr/developer-guides/examples/tracking-job-postings">
    Recevez un webhook plutôt que d'interroger périodiquement.
  </Card>
</CardGroup>
