# Read, create and unpublish jobs through the API

Source: https://docs.coworkies.com/api/jobs/

> Use job filters, correct pagination, validated creation payloads, idempotency and space-scoped unpublishing.

## Read active jobs

**`GET /v2/jobs`** requires `jobs:read`, broad `read`, or another scope that grants the required read access.

| Query | Meaning |
|---|---|
| `q` | Search title, company and tags. |
| `job_type` | `fulltime`, `parttime`, `freelance` or `internship`. |
| `remote` | Filter remote work with `true` or `false`. |
| `city` | City slug, such as `berlin`. |
| `page`, `per_page` | Used when server-side pagination is enabled; maximum 50 per page. |

```bash
curl --fail-with-body --max-time 30   'https://api.coworkies.com/v2/jobs?city=berlin&job_type=fulltime'   -H "X-API-Key: ${COWORKIES_API_KEY}"
```

A space-scoped key returns that space's jobs. Read the array in `data.jobs`. If `data.pagination` exists, use `has_next` and `current_page` to fetch further pages. Otherwise the server returns the complete matching list with `data.total`; do not assume `per_page` limits it.

## Create a job

**`POST /v2/jobs`** requires `jobs:write` or broad `write`. Send JSON.

| Required field | Value |
|---|---|
| `title` | Job title. |
| `company` | Hiring company name. |
| `description` | Text or basic HTML (`p`, `br`, `ul`, `ol`, `li`, `h2`, `h3`, `strong`, `em`, `a`). |
| `job_type` | `fulltime`, `parttime`, `freelance` or `internship`. |
| `tags` | Comma-separated tags. |
| `id_city` **or** `city_name` | Confirmed city ID or a name the API can resolve. |

Optional fields include `external_url` (original listing), `apply_url` (application destination), `is_remote` (`0` or `1`), `inv_email`, `currency` (`EUR`, `USD`, `GBP`), `sal_min`, `sal_max`, `id_space` and `id_plan` (default `5`). `sal_min` cannot exceed `sal_max`. Check the full reference for all optional fields.

The key's space is assigned automatically. A conflicting `id_space` is rejected. Tags are trimmed, lowercased and deduplicated. City-name resolution tries an exact match and then a prefix match; use a confirmed `id_city` when the name is ambiguous. The source URL receives a Coworkies referral parameter.

```bash
# Use a unique value for a new job; retain it for retries of this request.
COWORKIES_JOB_REQUEST_ID='space-job-community-manager-001'
curl --fail-with-body --max-time 30   'https://api.coworkies.com/v2/jobs'   -X POST   -H "X-API-Key: ${COWORKIES_API_KEY}"   -H 'Content-Type: application/json'   -H "Idempotency-Key: ${COWORKIES_JOB_REQUEST_ID}"   -d '{
    "title": "Community Manager",
    "company": "Example Workspace",
    "description": "Lead member experience at our Berlin workspace.",
    "job_type": "fulltime",
    "city_name": "Berlin",
    "tags": "community,events,hospitality",
    "apply_url": "https://example.com/careers/apply",
    "is_remote": 0,
    "currency": "EUR",
    "sal_min": 35000,
    "sal_max": 45000
  }'
```

### Check the publication result

For a confirmed **Pro space**, a new API job can be published as **`active`** automatically. Other space-key jobs start as **`draft`**. Trusted platform importers can also auto-publish. The client cannot force the initial status by adding a `status` field.

Always inspect `data.status`, `data.action`, `data.job_id` and the returned view/edit/payment links. Success alone does not mean a job is publicly visible. Follow the returned edit or payment route when further action is needed.

### Deduplication and retries

The API matches a fingerprint of normalized title, company, city and source URL. A match updates the existing job; `data.action` distinguishes `created` from `updated`. An existing expired or paused job is not automatically made active by a matching update.

An `Idempotency-Key` (up to 200 characters) avoids repeating a successful creation on an exact retry. Reuse it for that request, use a new one for a new operation, and handle an in-flight `409` or rate-limited `429` as described in [API errors](https://docs.coworkies.com/api/authentication/).

## Unpublish a job

**`POST /v2/jobs/unpublish`** requires job write access and a job belonging to the key's space.

```bash
curl --fail-with-body --max-time 30   'https://api.coworkies.com/v2/jobs/unpublish'   -X POST   -H "X-API-Key: ${COWORKIES_API_KEY}"   -H 'Content-Type: application/json'   -d '{"job_id": 1234}'
```

Replace `1234` with the saved `data.job_id`. A successful removal returns an expired status and an `unpublished` action. A job already expired or closed returns `already_unpublished`. This removes the listing from active results; it does not delete the job record.
