# removeCandidateAccessCircleMember

Source: /openapi/thomas-federated.openapi.json

## Operation

| Method | URL |
|---|---|
| DELETE | https://api.thomas.co/v1/candidates/{id}/access-circle/members |

| Field | Value |
|---|---|
| operationId | removeCandidateAccessCircleMember |
| method | DELETE |
| server | https://api.thomas.co |
| path | /v1/candidates/{id}/access-circle/members |
| tags | `Recruitment` |
| summary | Remove a member from a candidate’s access circle |
| badges | `{"name":"Admin"}`, `{"name":"Owner"}` |
| scopes | `users:w` |

## Description

Remove an individual from the candidate’s access circle. The last owner of a circle cannot be removed. A Partner API client may call it only on behalf of a named person (`Thomas-On-Behalf-Of`) who manages the circle, with a tenant context and `users:w`, and may send an optional `Idempotency-Key`.

## Request Parameters

| Name | In | Required | Schema | Description |
|---|---|---|---|---|
| id | path | true | string |  |
| Idempotency-Key | header | false | string | An opaque client-generated key, 1-255 visible ASCII characters excluding comma. Optional, and recommended for every write. Repeating a request with the same key and the same canonical request returns the ORIGINAL response instead of performing the work twice. Reusing the key for a DIFFERENT canonical request is refused with 409 IDEMPOTENCY_KEY_REUSED, and an equivalent request still in flight is refused with 409 IDEMPOTENCY_REQUEST_IN_PROGRESS and a Retry-After header. Omit it and the operation behaves exactly as it does without this header: the work is performed, and no replay protection applies. Sending the header with an EMPTY value counts as omitting it; any other malformed value — a repeated header, a comma-separated pair, or a value outside the charset or length above — is refused with 400 IDEMPOTENCY_KEY_INVALID. |
| Thomas-On-Behalf-Of | header | true | string | Sent only by a Partner API client, to act as one named person: thomas:<companyIndividualId> or partner:<partnerReference>. A Partner must send it on this operation (without it the call is refused with 403 PRINCIPAL_TYPE_NOT_ALLOWED); a signed-in person never sends it. |
| Thomas-Tenant-Id | header | true | string:uuid | Required for API clients: the Tenant this call acts in. Send exactly one. Signed-in users don't send it — their Tenant comes from their session. The header only selects the Tenant; your Grant for it decides access, and is checked on every call. |

## Request Body

| Content type | Required | Schema refs |
|---|---|---|
| application/json | true | #/components/schemas/RemoveAccessCircleMemberDto |

## Responses

| Status | Description | Schema refs |
|---|---|---|
| 200 | The refreshed circle summary | #/components/schemas/AccessCircleMemberMutationResponseDto |
| 400 | Invalid UUID format for id parameter, a request body that fails validation, a malformed tenant or person selector, or an Idempotency-Key sent in a shape that cannot be bound. Also returned when the Thomas-On-Behalf-Of header is repeated or malformed. | #/components/schemas/ApiErrorResponseDto |
| 401 | Invalid or missing authentication token (AUTH_TOKEN_INVALID) | #/components/schemas/ApiErrorResponseDto |
| 403 | Refused when the caller has insufficient role (owner or admin required), envelope `AUTH_INSUFFICIENT_ROLE`, or when the tenant’s effective plan tier does not include the Candidates capability, envelope `INSUFFICIENT_TIER` — a Partner acting on behalf of a person is held to the tenant’s plan too. Removing the circle’s last owner is refused with `ACCESS_GROUP_LAST_OWNER`. Also returned when a Partner API client calls without Thomas-On-Behalf-Of. | #/components/schemas/ApiErrorResponseDto |
| 404 | The id resolves to no candidate this caller may act on in this tenant. A missing id and another tenant’s id answer identically. On behalf of a person, a candidate outside that person’s access circles answers identically too, and an unavailable named person is refused. Also returned when the person named in Thomas-On-Behalf-Of is unavailable. | #/components/schemas/ApiErrorResponseDto |
| 409 | The circle changed concurrently (ACCESS_GROUP_CONCURRENT_MODIFICATION). The Idempotency-Key may also conflict with an attempt already recorded against it. | #/components/schemas/ApiErrorResponseDto |
| 429 | Rate limit exceeded. | #/components/schemas/ApiErrorResponseDto |

### Response 409 headers

| Name | Description | Schema |
|---|---|---|
| Retry-After | Present as `1` only when an equivalent idempotent request is in progress | {"type":"string","example":"1"} |

### Response 429 headers

| Name | Description | Schema |
|---|---|---|
| Retry-After | Seconds until the rate-limit block expires before retrying. | {"type":"integer","minimum":0} |
| RateLimit-Limit | Configured request limit for the active rate-limit window. | {"type":"integer"} |
| RateLimit-Remaining | Requests remaining in the active rate-limit window; zero when blocked. | {"type":"integer"} |
| RateLimit-Reset | Seconds until the rate-limit block expires. | {"type":"integer","minimum":0} |

## Artifact Examples

### Response 400 example — HTTP_BAD_REQUEST (Malformed UUID parameter)

```json
{
  "statusCode": 400,
  "message": "Validation failed (uuid is expected)",
  "error": "HTTP_BAD_REQUEST"
}
```

### Response 400 example — HTTP_BAD_REQUEST (Request validation failed)

```json
{
  "statusCode": 400,
  "message": "Validation failed",
  "error": "HTTP_BAD_REQUEST",
  "details": {
    "validationIssues": [
      {
        "path": "$",
        "rule": "invalid_type"
      }
    ]
  }
}
```

### Response 400 example — ACCESS_GROUP_PRINCIPAL_TYPE_UNSUPPORTED

```json
{
  "statusCode": 400,
  "message": "Only individual access-circle principals are supported",
  "error": "ACCESS_GROUP_PRINCIPAL_TYPE_UNSUPPORTED"
}
```

### Response 400 example — AUTH_TENANT_CONTEXT_INVALID (Malformed person selector)

```json
{
  "statusCode": 400,
  "message": "Exactly one valid Thomas-On-Behalf-Of header is required",
  "error": "AUTH_TENANT_CONTEXT_INVALID"
}
```

### Response 400 example — AUTH_TENANT_CONTEXT_INVALID (Missing or malformed tenant selector)

```json
{
  "statusCode": 400,
  "message": "Exactly one valid Thomas-Tenant-Id header is required",
  "error": "AUTH_TENANT_CONTEXT_INVALID"
}
```

### Response 400 example — IDEMPOTENCY_KEY_INVALID

```json
{
  "statusCode": 400,
  "message": "Exactly one valid Idempotency-Key header is required",
  "error": "IDEMPOTENCY_KEY_INVALID"
}
```

### Response 401 example

```json
{
  "statusCode": 401,
  "message": "Invalid or missing authentication token",
  "error": "AUTH_TOKEN_INVALID"
}
```

### Response 403 example — AUTH_INSUFFICIENT_ROLE

```json
{
  "statusCode": 403,
  "message": "Insufficient role privileges",
  "error": "AUTH_INSUFFICIENT_ROLE"
}
```

### Response 403 example — ACCESS_GROUP_LAST_OWNER

```json
{
  "statusCode": 403,
  "message": "Cannot remove the last owner of an access circle",
  "error": "ACCESS_GROUP_LAST_OWNER"
}
```

### Response 403 example — AUTH_TENANT_NOT_GRANTED

```json
{
  "statusCode": 403,
  "message": "API client is not granted access to this tenant",
  "error": "AUTH_TENANT_NOT_GRANTED"
}
```

### Response 403 example — PRINCIPAL_TYPE_NOT_ALLOWED

```json
{
  "statusCode": 403,
  "message": "API client is not permitted to call this operation",
  "error": "PRINCIPAL_TYPE_NOT_ALLOWED"
}
```

### Response 404 example — CANDIDATE_CONFIDENTIAL_NOT_FOUND

```json
{
  "statusCode": 404,
  "message": "Candidate not found",
  "error": "CANDIDATE_CONFIDENTIAL_NOT_FOUND"
}
```

### Response 404 example — ACCESS_GROUP_MEMBER_NOT_FOUND

```json
{
  "statusCode": 404,
  "message": "Access-circle member not found",
  "error": "ACCESS_GROUP_MEMBER_NOT_FOUND"
}
```

### Response 404 example — AUTH_ON_BEHALF_PERSON_NOT_AVAILABLE

```json
{
  "statusCode": 404,
  "message": "The named person is not available for this operation",
  "error": "AUTH_ON_BEHALF_PERSON_NOT_AVAILABLE"
}
```

### Response 409 example — ACCESS_GROUP_CONCURRENT_MODIFICATION

```json
{
  "statusCode": 409,
  "message": "Access circle was concurrently modified; retry the request",
  "error": "ACCESS_GROUP_CONCURRENT_MODIFICATION"
}
```

### Response 409 example — IDEMPOTENCY_KEY_REUSED

```json
{
  "statusCode": 409,
  "message": "This Idempotency-Key was already used for a different request",
  "error": "IDEMPOTENCY_KEY_REUSED"
}
```

### Response 409 example — IDEMPOTENCY_REQUEST_IN_PROGRESS

```json
{
  "statusCode": 409,
  "message": "An equivalent request is already in progress",
  "error": "IDEMPOTENCY_REQUEST_IN_PROGRESS"
}
```

### Response 429 example

```json
{
  "statusCode": 429,
  "message": "ThrottlerException: Too Many Requests",
  "error": "HTTP_TOO_MANY_REQUESTS"
}
```
