> ## Documentation Index
> Fetch the complete documentation index at: https://docs.clinia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Profiles & Relationships

> Understand how to define schemas and validation rules in each source

Profiles are the schema contracts that govern resources under a source. They specify which properties exist, which [data types](/explanation/data-types/base-types) they use, and which validation rules or vocabularies apply. Every resource instance references a profile key, so profiles are the backbone of data quality in the registry.

## Scope and keys

* **Per-source uniqueness** — Profile keys are unique within a source. Two sources can reuse the same key.
* **API usage** — You reference a profile key when writing resources, defining relationships, configuring partitions, or declaring pipelines.
* **Versioning** — Updating a profile changes which data future writes must respect. Existing records remain untouched until revalidated through a pipeline or reingested.

## Properties and validation

Each property declares:

* A type (`symbol`, `integer`, `address`, custom objects, arrays…)
* Optional `rules` for validation (required, min/max, enum, pattern, vocabulary bindings)
* Whether it can repeat (`array`) or embed structured objects (`object`)

Profiles integrate tightly with [field validation](/explanation/field-validation/basic) so that ingestion rejects records that violate the contract.

## Contained resources

Contained profiles let you model complex data without multiplying top-level resources.

### When to use contained profiles

* The component depends entirely on a single parent resource.
* You must allow multiple instances (for example, a clinic with many insurance contracts).

### When not to use contained profiles

* The component should be discoverable on its own (queryable partition collection).
* Multiple parent resources must reference the same record.
* You need graph relationships to or from that component.

In those cases, create a different profile and connect records with relationships instead.

## Example profile

```bash {collectForTests=profileClinic} theme={null}
curl -X PUT "https://$CLINIA_WORKSPACE/sources/clinics/v1/collections/clinic" \
  -H "X-Clinia-API-Key: $CLINIA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "type": "resources",
  "profile": {
    "description": "Clinic profile",
    "properties": {
      "address": {
        "type": "address",
        "properties": {
          "type": {
            "type": "code",
            "rules": [
              {
                "enum": [
                  "postal",
                  "physical",
                  "both"
                ]
              }
            ]
          }
        }
      }
    },
    "contained": {
      "weeklyHoursOfOperation": {
        "cardinality": "0:1",
        "properties": {
          "monday": {
            "type": "object",
            "properties": {
              "open": {
                "type": "time",
                "rules": [
                  {
                    "required": true
                  }
                ]
              },
              "close": {
                "type": "time",
                "rules": [
                  {
                    "required": true
                  }
                ]
              }
            }
          },
          "tuesday": {
            "type": "object",
            "properties": {
              "open": {
                "type": "time",
                "rules": [
                  {
                    "required": true
                  }
                ]
              },
              "close": {
                "type": "time",
                "rules": [
                  {
                    "required": true
                  }
                ]
              }
            }
          }
        }
      }
    }
  }
}'
```

This profile:

* Uses the Clinia [`address`](/explanation/data-types/clinia-types#address) complex type while layering custom validation.
* Embeds a contained profile to track opening hours without creating an independent resource.
* Keeps ingestion strict by validating enums and required fields.
