# personalityCarryOverAck

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

## Operation

| Method | URL |
|---|---|
| POST | https://api.thomas.co/v1/personality/carry-over-acknowledgements |

| Field | Value |
|---|---|
| operationId | personalityCarryOverAck |
| method | POST |
| server | https://api.thomas.co |
| path | /v1/personality/carry-over-acknowledgements |
| tags | `Personality` |
| summary | Record the one-time carry-over acknowledgement ("I understand") |
| badges | None |
| scopes | `users:w` |

## Request Parameters

| Name | In | Required | Schema | Description |
|---|---|---|---|---|
| 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-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. |
| 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 signed-in person never sends it. |

## Request Body

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

## Responses

| Status | Description | Schema refs |
|---|---|---|
| 201 | The acknowledgement register row. A repeat for the same result returns the existing row. | #/components/schemas/CarryOverAcknowledgementResponseDto |
| 400 | Invalid request payload. The Idempotency-Key header may also be 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 | A signed-in person is refused (PERSONALITY_CARRY_OVER_NOT_SUBJECT) only if the resolved result is not their own, a defence-in-depth check the current resolver cannot trigger. An API client is refused before any tenant data is read or changed when its tenant context, Grant or scope does not authorise the operation (AUTH_TENANT_NOT_GRANTED), when its service membership is absent (AUTH_SERVICE_MEMBERSHIP_MISSING), or when the operation is not published to its principal kind (PRINCIPAL_TYPE_NOT_ALLOWED). An API client holds no organisation role, so AUTH_INSUFFICIENT_ROLE never applies to it. Also returned when a Partner API client calls without Thomas-On-Behalf-Of. | #/components/schemas/ApiErrorResponseDto |
| 404 | The resultId is not the person's current committed Personality result. Also returned when the person named in Thomas-On-Behalf-Of is unavailable. | #/components/schemas/ApiErrorResponseDto |
| 409 | The result is not a carried-over recruitment result, or the acknowledgement could not be recorded. 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

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

### Response 400 example — IDEMPOTENCY_KEY_INVALID

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

### Response 400 example — AUTH_TENANT_CONTEXT_INVALID

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

### Response 401 example

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

### Response 403 example — PERSONALITY_CARRY_OVER_NOT_SUBJECT

```json
{
  "statusCode": 403,
  "message": "The caller is not the subject of this personality result",
  "error": "PERSONALITY_CARRY_OVER_NOT_SUBJECT"
}
```

### Response 403 example — INSUFFICIENT_TIER

```json
{
  "statusCode": 403,
  "message": "All instruments requires the Professional plan.",
  "error": "INSUFFICIENT_TIER"
}
```

### 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 — AUTH_SERVICE_MEMBERSHIP_MISSING

```json
{
  "statusCode": 403,
  "message": "API client has no active service membership in this tenant",
  "error": "AUTH_SERVICE_MEMBERSHIP_MISSING"
}
```

### 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 — PERSONALITY_CARRY_OVER_RESULT_NOT_FOUND

```json
{
  "statusCode": 404,
  "message": "No current committed personality result matches this resultId",
  "error": "PERSONALITY_CARRY_OVER_RESULT_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 — PERSONALITY_CARRY_OVER_NOT_RECRUITMENT

```json
{
  "statusCode": 409,
  "message": "Personality result has origin 'employment', not 'recruitment'",
  "error": "PERSONALITY_CARRY_OVER_NOT_RECRUITMENT"
}
```

### Response 409 example — PERSONALITY_CARRY_OVER_CONFLICT

```json
{
  "statusCode": 409,
  "message": "Carry-over acknowledgement hit a unique conflict with no committed row",
  "error": "PERSONALITY_CARRY_OVER_CONFLICT"
}
```

### 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"
}
```
