# Workspaces and account

> List, create, rename and erase the workspaces that keep each customer apart, read the credits left, and check that the API is up.

Source: https://hirelayer.co/api-docs/account · Markdown: https://hirelayer.co/api-docs/account.md

## Workspaces

A workspace holds the resumes, jobs and scores of one of your customers. Every call names it in the `HireLayer-Workspace` header, `default` when the header is absent, and creates it on first use: see [Workspaces](https://hirelayer.co/api-docs/authentication.md#workspaces). These endpoints list the workspaces, give one a display name or impose the [no-storage mode](https://hirelayer.co/api-docs/authentication.md#storage) on it, and erase one with everything it holds. They are free.

### List workspaces

`GET https://hirelayer.co/api/v4/workspaces`

`default` first, then the others, oldest first. Free.

- **Authentication:** `X-API-Key` header
- **Billing:** Free
- **Client timeout:** at least 30 seconds

#### Example request

**cURL**

```bash
curl https://hirelayer.co/api/v4/workspaces \
  -H "X-API-Key: $HIRELAYER_API_KEY"
```

**Python**

```python
import os

import requests

response = requests.get(
    "https://hirelayer.co/api/v4/workspaces",
    headers={"X-API-Key": os.environ["HIRELAYER_API_KEY"]},
    timeout=30,
)
response.raise_for_status()

data = response.json()
print(data["data"])
```

**TypeScript**

```typescript
const response = await fetch('https://hirelayer.co/api/v4/workspaces', {
  headers: {
    'X-API-Key': process.env.HIRELAYER_API_KEY!,
  },
  signal: AbortSignal.timeout(30_000),
})

if (!response.ok) {
  throw new Error(`HireLayer ${response.status}: ${await response.text()}`)
}

const data = await response.json()
console.log(data.data)
```

#### Response `200`

The workspaces.

| Field | Type | Description |
| --- | --- | --- |
| `data` | `object[]` |  |
| `data[].workspace_id` | `string` |  |
| `data[].name` | `string \| null` |  |
| `data[].do_not_store_data` | `boolean` | Every call of this workspace runs without storage. |
| `data[].jobs_count` | `integer` | ≥ 0. |
| `data[].resumes_count` | `integer` | ≥ 0. |
| `data[].created_at` | `string (date-time) \| null` |  |

#### Errors

| Status | `error.code` | `error.message` | When | Retry |
| --- | --- | --- | --- | --- |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `The X-API-Key header is missing.` | No `X-API-Key` header. | Fix, then retry |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `Authorization: Bearer is not accepted: send the key in the X-API-Key header.` | The key sent as `Authorization: Bearer`: it goes in `X-API-Key`. | Fix, then retry |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `The key goes in the X-API-Key header, not in the URL.` | The key sent in the URL: it goes in `X-API-Key`. | Fix, then retry |
| `401` | [`invalid_api_key`](https://hirelayer.co/api-docs/errors.md#invalid_api_key) | `Invalid API key: it is unknown, malformed or revoked.` | The key is unknown, malformed or revoked. | Fix, then retry |
| `500` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `Internal error: retry later. If it persists, contact support with the request_id.` | An unexpected error. | Retry with backoff |
| `502` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The service could not be reached: retry later.` | The service could not be reached. | Retry with backoff |
| `503` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The credit service is briefly unavailable: retry in a second.` | The credit service is briefly unavailable. Headers: `Retry-After: <seconds>`. | Retry with backoff |
| `504` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The service did not answer in time. The change may still be applied: read it before sending it again.` | No answer in time. | Retry with backoff |

Example error (`401`):

```json
{
  "error": {
    "code": "missing_api_key",
    "message": "The X-API-Key header is missing.",
    "doc_url": "https://hirelayer.co/api-docs/errors#missing_api_key"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}
```

### Create or rename a workspace

`PUT https://hirelayer.co/api/v4/workspaces/{workspace_id}`

Creates a workspace for one of your customers, gives it a new display name, or imposes the no-storage mode on it. Its id never changes. Free.

- **Authentication:** `X-API-Key` header
- **Content type:** `application/json`
- **Billing:** Free
- **Client timeout:** at least 30 seconds

- **`do_not_store_data: false`** lifts it; nothing processed meanwhile was kept.
- A field left out keeps its current value.

#### Path parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `workspace_id` | `string` | Yes | Letters, digits and `. _ : ~ -`, up to 200 characters. |

#### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | `string` | No | 1–200 characters. |
| `do_not_store_data` | `boolean` | No | Enterprise plan only. Impose the no-storage mode on every call of this workspace. |

#### Example request

**cURL**

```bash
curl -X PUT https://hirelayer.co/api/v4/workspaces/acme \
  -H "X-API-Key: $HIRELAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme"
  }'
```

**Python**

```python
import os

import requests

response = requests.put(
    "https://hirelayer.co/api/v4/workspaces/acme",
    headers={"X-API-Key": os.environ["HIRELAYER_API_KEY"]},
    json={
        "name": "Acme",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()
print(data["workspace_id"])
```

**TypeScript**

```typescript
const response = await fetch('https://hirelayer.co/api/v4/workspaces/acme', {
  method: 'PUT',
  headers: {
    'X-API-Key': process.env.HIRELAYER_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Acme',
  }),
  signal: AbortSignal.timeout(30_000),
})

if (!response.ok) {
  throw new Error(`HireLayer ${response.status}: ${await response.text()}`)
}

const data = await response.json()
console.log(data.workspace_id)
```

#### Response `200`

Renamed.

| Field | Type | Description |
| --- | --- | --- |
| `workspace_id` | `string` |  |
| `name` | `string \| null` |  |
| `do_not_store_data` | `boolean` | Every call of this workspace runs without storage. |
| `jobs_count` | `integer` | ≥ 0. |
| `resumes_count` | `integer` | ≥ 0. |
| `created_at` | `string (date-time) \| null` |  |

#### Response `201`

Created.

| Field | Type | Description |
| --- | --- | --- |
| `workspace_id` | `string` |  |
| `name` | `string \| null` |  |
| `do_not_store_data` | `boolean` | Every call of this workspace runs without storage. |
| `jobs_count` | `integer` | ≥ 0. |
| `resumes_count` | `integer` | ≥ 0. |
| `created_at` | `string (date-time) \| null` |  |

#### Errors

| Status | `error.code` | `error.message` | When | Retry |
| --- | --- | --- | --- | --- |
| `400` | [`invalid_request`](https://hirelayer.co/api-docs/errors.md#invalid_request) | `name must be 200 characters or less.` | `param`: `name`. `name` over 200 characters. | Fix, then retry |
| `400` | [`invalid_request`](https://hirelayer.co/api-docs/errors.md#invalid_request) | `The default workspace always exists and has no name to set.` | `param`: `workspace_id`. A name for the workspace `default`. | Fix, then retry |
| `400` | [`invalid_request`](https://hirelayer.co/api-docs/errors.md#invalid_request) | `do_not_store_data must be true or false.` | `param`: `do_not_store_data`. `do_not_store_data` is not a boolean. | Fix, then retry |
| `400` | [`invalid_request`](https://hirelayer.co/api-docs/errors.md#invalid_request) | `workspace_id must contain letters, digits and . _ : ~ -, up to 200 characters.` | `param`: `workspace_id`. `workspace_id` in the path is not a valid id. | Fix, then retry |
| `400` | [`invalid_request`](https://hirelayer.co/api-docs/errors.md#invalid_request) | `Unknown field label.` | `param`: `label`. A field the call does not take. | Fix, then retry |
| `400` | [`invalid_request`](https://hirelayer.co/api-docs/errors.md#invalid_request) | `The request body is not valid JSON.` | The body is not valid JSON, not an object, or not sent as `application/json`. | Fix, then retry |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `The X-API-Key header is missing.` | No `X-API-Key` header. | Fix, then retry |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `Authorization: Bearer is not accepted: send the key in the X-API-Key header.` | The key sent as `Authorization: Bearer`: it goes in `X-API-Key`. | Fix, then retry |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `The key goes in the X-API-Key header, not in the URL.` | The key sent in the URL: it goes in `X-API-Key`. | Fix, then retry |
| `401` | [`invalid_api_key`](https://hirelayer.co/api-docs/errors.md#invalid_api_key) | `Invalid API key: it is unknown, malformed or revoked.` | The key is unknown, malformed or revoked. | Fix, then retry |
| `403` | [`enterprise_plan_required`](https://hirelayer.co/api-docs/errors.md#enterprise_plan_required) | `do_not_store_data is available on the Enterprise plan only. Nothing was processed or billed.` | `param`: `do_not_store_data`. `do_not_store_data: true` below the Enterprise plan. | Do not retry |
| `413` | [`payload_too_large`](https://hirelayer.co/api-docs/errors.md#payload_too_large) | `The request body must be 10 MB or less.` | The body is over 10 MB. | Fix, then retry |
| `500` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `Internal error: retry later. If it persists, contact support with the request_id.` | An unexpected error. | Retry with backoff |
| `502` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The service could not be reached: retry later.` | The service could not be reached. | Retry with backoff |
| `503` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The credit service is briefly unavailable: retry in a second.` | The credit service is briefly unavailable. Headers: `Retry-After: <seconds>`. | Retry with backoff |
| `504` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The service did not answer in time. The change may still be applied: read it before sending it again.` | No answer in time. | Retry with backoff |

Example error (`400`):

```json
{
  "error": {
    "code": "invalid_request",
    "message": "name must be 200 characters or less.",
    "param": "name",
    "doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}
```

#### Behavior

- **`do_not_store_data: true` (Enterprise plan only, else `403 enterprise_plan_required`):** every later call sent with this workspace runs as with `do_not_store_data=true`, whatever the call sends; both searches, and the writes that would store something in it (`PUT /resumes/{application_id}`, `PUT /jobs/{job_id}`, `POST /jobs/{job_id}/criteria`, `PATCH /jobs/{job_id}/criteria/{criterion_id}`), answer `400 storage_required`. What the workspace already holds stays until you erase it (`DELETE /workspaces/{workspace_id}`). Calls sent without the `HireLayer-Workspace` header go to `default`: they are covered only when `default` itself is set this way.

### Erase a workspace

`DELETE https://hirelayer.co/api/v4/workspaces/{workspace_id}`

Erases every job, resume, file and score of the workspace, for example when your customer leaves. Free.

- **Authentication:** `X-API-Key` header
- **Billing:** Free
- **Client timeout:** at least 60 seconds

#### Path parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `workspace_id` | `string` | Yes | Letters, digits and `. _ : ~ -`, up to 200 characters. |

#### Example request

**cURL**

```bash
curl -X DELETE https://hirelayer.co/api/v4/workspaces/acme \
  -H "X-API-Key: $HIRELAYER_API_KEY"
```

**Python**

```python
import os

import requests

response = requests.delete(
    "https://hirelayer.co/api/v4/workspaces/acme",
    headers={"X-API-Key": os.environ["HIRELAYER_API_KEY"]},
    timeout=60,
)
response.raise_for_status()
print(response.status_code)
```

**TypeScript**

```typescript
const response = await fetch('https://hirelayer.co/api/v4/workspaces/acme', {
  method: 'DELETE',
  headers: {
    'X-API-Key': process.env.HIRELAYER_API_KEY!,
  },
  signal: AbortSignal.timeout(60_000),
})

if (!response.ok) {
  throw new Error(`HireLayer ${response.status}: ${await response.text()}`)
}

console.log(response.status)
```

#### Response `204`

Erased.

#### Errors

| Status | `error.code` | `error.message` | When | Retry |
| --- | --- | --- | --- | --- |
| `400` | [`invalid_request`](https://hirelayer.co/api-docs/errors.md#invalid_request) | `workspace_id must contain letters, digits and . _ : ~ -, up to 200 characters.` | `param`: `workspace_id`. `workspace_id` in the path is not a valid id. | Fix, then retry |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `The X-API-Key header is missing.` | No `X-API-Key` header. | Fix, then retry |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `Authorization: Bearer is not accepted: send the key in the X-API-Key header.` | The key sent as `Authorization: Bearer`: it goes in `X-API-Key`. | Fix, then retry |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `The key goes in the X-API-Key header, not in the URL.` | The key sent in the URL: it goes in `X-API-Key`. | Fix, then retry |
| `401` | [`invalid_api_key`](https://hirelayer.co/api-docs/errors.md#invalid_api_key) | `Invalid API key: it is unknown, malformed or revoked.` | The key is unknown, malformed or revoked. | Fix, then retry |
| `404` | [`not_found`](https://hirelayer.co/api-docs/errors.md#not_found) | `No workspace acme: it was never created, and nothing was ever stored in it.` | `param`: `workspace_id`. The workspace was never created or used. | Do not retry |
| `500` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `Internal error: retry later. If it persists, contact support with the request_id.` | An unexpected error. | Retry with backoff |
| `502` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The service could not be reached: retry later.` | The service could not be reached. | Retry with backoff |
| `503` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The erasure could not be finished: send the same call again to finish it.` | An erasure could not be finished: the same call finishes it. Headers: `Retry-After: <seconds>`. | Retry with backoff |
| `504` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The service did not answer in time. The change may still be applied: read it before sending it again.` | No answer in time. | Retry with backoff |

Example error (`400`):

```json
{
  "error": {
    "code": "invalid_request",
    "message": "workspace_id must contain letters, digits and . _ : ~ -, up to 200 characters.",
    "param": "workspace_id",
    "doc_url": "https://hirelayer.co/api-docs/errors#invalid_request"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}
```

## Account and status

`GET /account` gives the plan and the credits left of the key’s account. `GET /health` answers without a key, for a monitoring probe. Both are free.

### Get the account

`GET https://hirelayer.co/api/v4/account`

The plan and the credits left of the key's account. Free.

- **Authentication:** `X-API-Key` header
- **Billing:** Free
- **Client timeout:** at least 30 seconds

#### Example request

**cURL**

```bash
curl https://hirelayer.co/api/v4/account \
  -H "X-API-Key: $HIRELAYER_API_KEY"
```

**Python**

```python
import os

import requests

response = requests.get(
    "https://hirelayer.co/api/v4/account",
    headers={"X-API-Key": os.environ["HIRELAYER_API_KEY"]},
    timeout=30,
)
response.raise_for_status()

data = response.json()
print(data["credits"])
```

**TypeScript**

```typescript
const response = await fetch('https://hirelayer.co/api/v4/account', {
  headers: {
    'X-API-Key': process.env.HIRELAYER_API_KEY!,
  },
  signal: AbortSignal.timeout(30_000),
})

if (!response.ok) {
  throw new Error(`HireLayer ${response.status}: ${await response.text()}`)
}

const data = await response.json()
console.log(data.credits)
```

#### Response `200`

The account.

| Field | Type | Description |
| --- | --- | --- |
| `account` | `object` |  |
| `account.email` | `string \| null` |  |
| `account.plan` | `string` | One of: `"free"`, `"starter"`, `"scale"`, `"pay_as_you_go"`, `"enterprise"`. |
| `credits` | `object` |  |
| `credits.available` | `integer \| null` | `null` on an unlimited plan. |
| `credits.unlimited` | `boolean` |  |

```json
{
  "account": {
    "email": "dev@example.com",
    "plan": "scale"
  },
  "credits": {
    "available": 4210,
    "unlimited": false
  }
}
```

#### Errors

| Status | `error.code` | `error.message` | When | Retry |
| --- | --- | --- | --- | --- |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `The X-API-Key header is missing.` | No `X-API-Key` header. | Fix, then retry |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `Authorization: Bearer is not accepted: send the key in the X-API-Key header.` | The key sent as `Authorization: Bearer`: it goes in `X-API-Key`. | Fix, then retry |
| `401` | [`missing_api_key`](https://hirelayer.co/api-docs/errors.md#missing_api_key) | `The key goes in the X-API-Key header, not in the URL.` | The key sent in the URL: it goes in `X-API-Key`. | Fix, then retry |
| `401` | [`invalid_api_key`](https://hirelayer.co/api-docs/errors.md#invalid_api_key) | `Invalid API key: it is unknown, malformed or revoked.` | The key is unknown, malformed or revoked. | Fix, then retry |
| `500` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `Internal error: retry later. If it persists, contact support with the request_id.` | An unexpected error. | Retry with backoff |
| `502` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The service could not be reached: retry later.` | The service could not be reached. | Retry with backoff |
| `503` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The credit service is briefly unavailable: retry in a second.` | The credit service is briefly unavailable. Headers: `Retry-After: <seconds>`. | Retry with backoff |
| `504` | [`internal_error`](https://hirelayer.co/api-docs/errors.md#internal_error) | `The service did not answer in time. The change may still be applied: read it before sending it again.` | No answer in time. | Retry with backoff |

Example error (`401`):

```json
{
  "error": {
    "code": "missing_api_key",
    "message": "The X-API-Key header is missing.",
    "doc_url": "https://hirelayer.co/api-docs/errors#missing_api_key"
  },
  "request_id": "6f1c2a4e-1d2b-4c3a-9e8f-0a1b2c3d4e5f"
}
```

### Service health

`GET https://hirelayer.co/api/v4/health`

No key needed. Free.

- **Authentication:** none
- **Billing:** Free
- **Client timeout:** at least 10 seconds

#### Example request

**cURL**

```bash
curl https://hirelayer.co/api/v4/health
```

**Python**

```python
import requests

response = requests.get(
    "https://hirelayer.co/api/v4/health",
    timeout=10,
)
response.raise_for_status()

data = response.json()
print(data["status"])
```

**TypeScript**

```typescript
const response = await fetch('https://hirelayer.co/api/v4/health', {
  signal: AbortSignal.timeout(10_000),
})

if (!response.ok) {
  throw new Error(`HireLayer ${response.status}: ${await response.text()}`)
}

const data = await response.json()
console.log(data.status)
```

#### Response `200`

The service answers.

| Field | Type | Description |
| --- | --- | --- |
| `status` | `string` | Value: `"healthy"`. |
| `service` | `string` |  |
| `timestamp` | `string (date-time)` |  |

```json
{
  "status": "healthy",
  "service": "hirelayer-api",
  "timestamp": "2026-10-27T09:00:00Z"
}
```

## Next

- [Limits and credits](https://hirelayer.co/api-docs/limits.md): What each HireLayer product costs, how large a call can be, and which client timeouts to use.
- [Authentication, workspaces and storage](https://hirelayer.co/api-docs/authentication.md): Authenticate every request with an X-API-Key header, keep each customer in its own workspace, and choose whether HireLayer stores what it processes.
