# Create a relationship on an entity

`POST /entities/{entity_uuid}/relationships`

- Base: `POST https://portal.watcheye.com.au/api/v1/entities/{entity_uuid}/relationships`

Create a relationship FROM the entity in the path TO another entity on your account. The two
entities can belong to different programs.

Direction is set by the order: the path entity becomes `from_entity_uuid` and the
`to_entity_uuid` in the body becomes the `to` side. To record the relationship the other way
around, send the request to the other entity instead.

A relationship of a given type is recorded once between two entities. For symmetric types
(such as `spouse_of`) the same pair counts as one relationship regardless of direction; a
repeat request returns `409`.

## Idempotency

This endpoint accepts the `Idempotency-Key` header so that retries on network failure are
safe. See the [Idempotency](/docs/guides/watcheye_api/idempotency) section of the
API guide for the full contract.

## Parameters

| Name | In | Type | Description |
|------|----|------|-------------|
| `entity_uuid` | path | string (uuid) | **Required.** The entity UUID (the `from` side of the relationship) |
| `Idempotency-Key` | header | string [max 255 characters] | Optional client-generated key (typically a UUID) that lets you safely retry a write request without risk of duplicate work or duplicate billing. A retry with the same key and body returns the original response verbatim, with the `Idempotent-Replay: true` response header. Honoured on `POST` requests only. See the [Idempotency](/docs/guides/watcheye_api/idempotency) section of the API guide for the full contract. Example: `8c4d3a18-2f63-4f9a-9f3a-9b1f5a7c2d4f` |

## Request body

The relationship details

| Field | Type | Description |
|-------|------|-------------|
| `to_entity_uuid` | string (uuid) | **Required.** UUID of the entity the relationship points to. Must be on your account and different from the path entity. |
| `relationship_type` | string | **Required.** The type of relationship. Each type permits only certain entity types on the `from` and `to` sides (for example `director_of` links an individual to a business); a request that pairs incompatible entity types is rejected with a 422. Some types (such as `associated_with`) require a `comment`. Enum: `spouse_of`, `director_of`, `shareholder_of`, `trustee_of`, `beneficiary_of`, `parent_of`, `sibling_of`, `employee_of`, `officer_of`, `partner_in`, `owner_of`, `buyer_of`, `seller_of`, `associated_with` Example: `director_of` |
| `percentage_ownership` | number (float) | Optional ownership percentage (0-100). Only meaningful for relationship types that support ownership (such as `shareholder_of`, `partner_in`, `owner_of`); ignored for other types. Drives ultimate beneficial owner tracing. Example: `40` |
| `effective_from` | string (date) | Optional date the relationship is effective from (YYYY-MM-DD). Example: `2024-01-01` |
| `effective_to` | string (date) | Optional date the relationship is effective until (YYYY-MM-DD). Must be on or after effective_from. Ignored (stored as null) for point-in-time relationship types (`buyer_of` and `seller_of`), which record a single dated event in `effective_from`. Example: `2025-01-01` |
| `comment` | string [max 255 characters] | Free-text comment. Max 255 characters. Optional for most relationship types, but required for some (such as `associated_with`). Example: `Appointed at the 2024 AGM.` |

**Sample request**

```json
{
    "to_entity_uuid": "00000000-0000-0000-0000-000000000000",
    "relationship_type": "director_of",
    "percentage_ownership": 40,
    "effective_from": "2024-01-01",
    "effective_to": "2025-01-01",
    "comment": "Appointed at the 2024 AGM."
}
```

## Responses

### 201 Relationship created

Content type: `application/json`

| Field | Type | Description |
|-------|------|-------------|
| `data` | object | A directed link between two entities on your account - for example a person who is a director of a company, the spouse of another person, or the beneficial owner of a trust. The two entities can belong to any program on your account. A relationship is stored once, in the direction it was created (`from_entity_uuid` -> `to_entity_uuid`). Both labels are returned so you can present the link from either entity's point of view: read `forward_label` when looking from the `from` entity and `inverse_label` when looking from the `to` entity. When `symmetric` is `true` the two labels are identical and the direction carries no extra meaning. Deleting a relationship is a soft-delete: the record is kept for audit / compliance purposes and a subsequent list call no longer returns it. |
| `data.uuid` | string (uuid) | The relationship's UUID Example: `7c1c0a8e-2b9f-4f0e-8d1a-1e2b3c4d5e6f` |
| `data.relationship_type` | string | The type of relationship. Enum: `spouse_of`, `director_of`, `shareholder_of`, `trustee_of`, `beneficiary_of`, `parent_of`, `sibling_of`, `employee_of`, `officer_of`, `partner_in`, `owner_of`, `buyer_of`, `seller_of`, `associated_with` Example: `director_of` |
| `data.forward_label` | string | Human-readable label when read from the `from` entity (e.g. "Director of"). Example: `Director of` |
| `data.inverse_label` | string | Human-readable label when read from the `to` entity (e.g. "Has director"). Example: `Has director` |
| `data.symmetric` | boolean | When `true` the relationship reads the same from both sides (e.g. "Spouse / de facto / domestic partner") and `forward_label` equals `inverse_label`. Example: `false` |
| `data.from_entity_uuid` | string (uuid) | UUID of the entity the relationship is recorded from. |
| `data.to_entity_uuid` | string (uuid) | UUID of the entity the relationship points to. |
| `data.percentage_ownership` | number (float) or null | Ownership percentage (0-100) for relationship types that support it (such as `shareholder_of`, `partner_in` and `owner_of`). Null for other types, or when an ownership relationship's percentage is unknown. Drives ultimate beneficial owner tracing. Example: `40` |
| `data.source` | string | How the relationship was recorded (e.g. `manual`, `workflow`, `report`, `kyb_discovery`, `import`). Example: `manual` |
| `data.effective_from` | string (date) or null | Optional date from which the relationship is effective (YYYY-MM-DD). Example: `2024-01-01` |
| `data.effective_to` | string (date) or null | Optional date the relationship is effective until (YYYY-MM-DD). Always null for point-in-time relationship types (`buyer_of` and `seller_of`), which record a single dated event in `effective_from`. |
| `data.comment` | string or null | Optional free-text comment describing the relationship. Example: `Appointed at the 2024 AGM.` |
| `data.created_at` | string (date-time) | Example: `2025-01-01T00:00:00Z` |
| `data.updated_at` | string (date-time) | Example: `2025-01-01T00:00:00Z` |
| `api_reference` | string (uuid) |  |

**Sample response**

```json
{
    "data": {
        "uuid": "7c1c0a8e-2b9f-4f0e-8d1a-1e2b3c4d5e6f",
        "relationship_type": "director_of",
        "forward_label": "Director of",
        "inverse_label": "Has director",
        "symmetric": false,
        "from_entity_uuid": "00000000-0000-0000-0000-000000000000",
        "to_entity_uuid": "00000000-0000-0000-0000-000000000000",
        "percentage_ownership": 40,
        "source": "manual",
        "effective_from": "2024-01-01",
        "effective_to": null,
        "comment": "Appointed at the 2024 AGM.",
        "created_at": "2025-01-01T00:00:00Z",
        "updated_at": "2025-01-01T00:00:00Z"
    },
    "api_reference": "00000000-0000-0000-0000-000000000000"
}
```

### 409 Conflict - either a request with this Idempotency-Key is currently being processed, or a relationship of this type already exists between these entities.

Content type: `application/json`

| Field | Type | Description |
|-------|------|-------------|
| `message` | string | Example: `A relationship of this type already exists between these entities.` |

**Sample response**

```json
{
    "message": "A relationship of this type already exists between these entities."
}
```

### 422 Idempotency-Key was reused with a different request body

Content type: `application/json`

| Field | Type | Description |
|-------|------|-------------|
| `message` | string | Example: `Idempotency-Key was reused with a different request body.` |

**Sample response**

```json
{
    "message": "Idempotency-Key was reused with a different request body."
}
```

Standard error responses: 400, 401, 403, 404, 429, 5XX (see [Common error responses](/docs/reference/general/common-error-responses.md))

