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

# Custom schemas for data ingestion

> Define custom data schemas in gu1 to ingest organization-specific fields, validate payload shapes, and store flexible attributes per entity.

## Overview

Custom Schemas allow you to define the structure of your data before importing it into gu1. Each schema describes the fields, types, validation rules, and metadata for your data source.

<Info>
  Schemas are organization-specific and can be marked as public to share across your organization.
</Info>

## Create Schema

Create a new custom schema for your data source.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST http://api.gu1.ai/custom-schemas \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Corporate KYB Data",
      "version": "1.0.0",
      "description": "Company information for KYB analysis",
      "type": "database",
      "category": "financial",
      "schemaData": {
        "fields": [
          {
            "name": "company_name",
            "type": "string",
            "required": true,
            "description": "Legal company name"
          },
          {
            "name": "tax_id",
            "type": "string",
            "required": true,
            "description": "Tax identification number"
          }
        ]
      },
      "isPublic": false
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('http://api.gu1.ai/custom-schemas', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      name: 'Corporate KYB Data',
      version: '1.0.0',
      description: 'Company information for KYB analysis',
      type: 'database',
      category: 'financial',
      schemaData: {
        fields: [
          {
            name: 'company_name',
            type: 'string',
            required: true,
            description: 'Legal company name'
          },
          {
            name: 'tax_id',
            type: 'string',
            required: true,
            description: 'Tax identification number'
          }
        ]
      },
      isPublic: false
    })
  });

  const data = await response.json();
  ```

  ```python Python theme={null}
  import requests

  headers = {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
  }

  data = {
      'name': 'Corporate KYB Data',
      'version': '1.0.0',
      'description': 'Company information for KYB analysis',
      'type': 'database',
      'category': 'financial',
      'schemaData': {
          'fields': [
              {
                  'name': 'company_name',
                  'type': 'string',
                  'required': True,
                  'description': 'Legal company name'
              },
              {
                  'name': 'tax_id',
                  'type': 'string',
                  'required': True,
                  'description': 'Tax identification number'
              }
          ]
      },
      'isPublic': False
  }

  response = requests.post(
      'http://api.gu1.ai/custom-schemas',
      headers=headers,
      json=data
  )
  ```
</CodeGroup>

### Request Body

| Field         | Type    | Required | Description                                                               |
| ------------- | ------- | -------- | ------------------------------------------------------------------------- |
| `name`        | string  | Yes      | Schema name (1-255 characters)                                            |
| `version`     | string  | No       | Version number (default: "1.0.0")                                         |
| `description` | string  | No       | Schema description                                                        |
| `type`        | enum    | Yes      | Schema type: `database`, `api`, `file`, `custom`                          |
| `category`    | enum    | Yes      | Category: `financial`, `identity`, `compliance`, `transaction`, `general` |
| `schemaData`  | object  | Yes      | Schema definition with fields                                             |
| `isPublic`    | boolean | No       | Share across organization (default: false)                                |

### Schema Data Object

| Field             | Type   | Required | Description                                  |
| ----------------- | ------ | -------- | -------------------------------------------- |
| `fields`          | array  | Yes      | Array of field definitions                   |
| `metadata`        | object | No       | Additional metadata (format, encoding, etc.) |
| `analysisResults` | object | No       | Auto-detection results                       |

### Field Definition

| Field         | Type    | Required | Description                                              |
| ------------- | ------- | -------- | -------------------------------------------------------- |
| `name`        | string  | Yes      | Field name                                               |
| `type`        | enum    | Yes      | `string`, `number`, `boolean`, `date`, `array`, `object` |
| `required`    | boolean | No       | Is field required (default: false)                       |
| `description` | string  | No       | Field description                                        |
| `format`      | string  | No       | Format hint (e.g., "email", "url")                       |
| `constraints` | object  | No       | Validation constraints                                   |
| `examples`    | array   | No       | Example values                                           |

### Constraints Object

```json theme={null}
{
  "minLength": 5,
  "maxLength": 100,
  "pattern": "^[A-Z0-9]+$",
  "enum": ["active", "inactive", "pending"],
  "min": 0,
  "max": 1000
}
```

### Response

```json theme={null}
{
  "success": true,
  "schema": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Corporate KYB Data",
    "version": "1.0.0",
    "description": "Company information for KYB analysis",
    "type": "database",
    "category": "financial",
    "organizationId": "org_abc123",
    "createdBy": "user_xyz789",
    "isPublic": false,
    "createdAt": "2025-10-03T12:00:00Z",
    "updatedAt": "2025-10-03T12:00:00Z",
    "schemaData": {
      "fields": [...]
    }
  }
}
```

## List Schemas

Get all schemas for your organization with optional filtering.

```bash theme={null}
GET /custom-schemas?type=database&category=financial&isPublic=false
```

### Query Parameters

| Parameter  | Type    | Description                                                                         |
| ---------- | ------- | ----------------------------------------------------------------------------------- |
| `type`     | enum    | Filter by type: `database`, `api`, `file`, `custom`                                 |
| `category` | enum    | Filter by category: `financial`, `identity`, `compliance`, `transaction`, `general` |
| `isPublic` | boolean | Filter by public/private schemas                                                    |

### Response

```json theme={null}
{
  "success": true,
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Corporate KYB Data",
      "version": "1.0.0",
      "type": "database",
      "category": "financial",
      "isPublic": false,
      "createdAt": "2025-10-03T12:00:00Z"
    }
  ],
  "meta": {
    "total": 1,
    "filters": {
      "type": "database",
      "category": "financial"
    }
  }
}
```

## Get Schema

Retrieve a specific schema by ID.

```bash theme={null}
GET /custom-schemas/:id
```

### Response

```json theme={null}
{
  "success": true,
  "schema": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Corporate KYB Data",
    "version": "1.0.0",
    "description": "Company information for KYB analysis",
    "type": "database",
    "category": "financial",
    "organizationId": "org_abc123",
    "createdBy": "user_xyz789",
    "isPublic": false,
    "createdAt": "2025-10-03T12:00:00Z",
    "updatedAt": "2025-10-03T12:00:00Z",
    "schemaData": {
      "fields": [
        {
          "name": "company_name",
          "type": "string",
          "required": true,
          "description": "Legal company name"
        },
        {
          "name": "tax_id",
          "type": "string",
          "required": true,
          "description": "Tax identification number"
        }
      ],
      "metadata": {
        "sourceFormat": "database",
        "encoding": "UTF-8"
      }
    }
  }
}
```

## Update Schema

Update an existing schema (partial updates supported).

```bash theme={null}
PATCH /custom-schemas/:id
```

### Request Body

```json theme={null}
{
  "description": "Updated description",
  "schemaData": {
    "fields": [
      {
        "name": "company_name",
        "type": "string",
        "required": true,
        "description": "Updated field description"
      }
    ]
  }
}
```

<Warning>
  Updating a schema's fields may affect existing mappings. Review dependent mappings before making changes.
</Warning>

### Response

```json theme={null}
{
  "success": true,
  "schema": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Corporate KYB Data",
    "version": "1.0.0",
    "description": "Updated description",
    "updatedAt": "2025-10-03T13:00:00Z",
    ...
  }
}
```

## Delete Schema

Delete a schema permanently.

```bash theme={null}
DELETE /custom-schemas/:id
```

<Warning>
  Deleting a schema will break existing field mappings that depend on it. Ensure no active mappings reference this schema.
</Warning>

### Response

```json theme={null}
{
  "success": true,
  "message": "Schema deleted successfully",
  "deletedId": "550e8400-e29b-41d4-a716-446655440000"
}
```

## Complete Example

Here's a complete banking customer schema with all features:

```json theme={null}
{
  "name": "Banking Customer Schema",
  "version": "2.0.0",
  "description": "Complete customer data structure for retail banking",
  "type": "database",
  "category": "financial",
  "schemaData": {
    "fields": [
      {
        "name": "customer_id",
        "type": "string",
        "required": true,
        "description": "Unique customer identifier",
        "format": "uuid",
        "constraints": {
          "pattern": "^CUST[0-9]{8}$"
        },
        "examples": ["CUST12345678", "CUST87654321"]
      },
      {
        "name": "full_name",
        "type": "string",
        "required": true,
        "description": "Customer full legal name",
        "constraints": {
          "minLength": 2,
          "maxLength": 200
        },
        "examples": ["John Doe", "Jane Smith"]
      },
      {
        "name": "email",
        "type": "string",
        "required": true,
        "description": "Primary email address",
        "format": "email",
        "constraints": {
          "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
        },
        "examples": ["john.doe@example.com"]
      },
      {
        "name": "date_of_birth",
        "type": "date",
        "required": true,
        "description": "Customer date of birth",
        "format": "ISO8601",
        "examples": ["1990-01-15"]
      },
      {
        "name": "account_balance",
        "type": "number",
        "required": false,
        "description": "Current account balance in USD",
        "constraints": {
          "min": 0
        },
        "examples": [1000.50, 50000.00]
      },
      {
        "name": "risk_level",
        "type": "string",
        "required": true,
        "description": "Customer risk classification",
        "constraints": {
          "enum": ["low", "medium", "high", "critical"]
        },
        "examples": ["low", "medium"]
      },
      {
        "name": "kyc_verified",
        "type": "boolean",
        "required": true,
        "description": "Whether KYC verification is complete",
        "examples": [true, false]
      },
      {
        "name": "account_types",
        "type": "array",
        "required": false,
        "description": "Types of accounts customer holds",
        "examples": [["checking", "savings"], ["credit"]]
      },
      {
        "name": "address",
        "type": "object",
        "required": false,
        "description": "Customer address details",
        "examples": [
          {
            "street": "123 Main St",
            "city": "New York",
            "state": "NY",
            "zip": "10001",
            "country": "US"
          }
        ]
      }
    ],
    "metadata": {
      "sourceFormat": "database",
      "encoding": "UTF-8",
      "delimiter": null,
      "hasHeaders": true
    }
  },
  "isPublic": false
}
```

## Error Responses

### Validation Error

```json theme={null}
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid schema data",
    "details": [
      {
        "field": "schemaData.fields[0].type",
        "message": "Invalid field type. Must be one of: string, number, boolean, date, array, object"
      }
    ]
  }
}
```

### Schema Not Found

```json theme={null}
{
  "success": false,
  "error": {
    "code": "SCHEMA_NOT_FOUND",
    "message": "Schema with ID 550e8400-e29b-41d4-a716-446655440000 not found"
  }
}
```

### Duplicate Schema

```json theme={null}
{
  "success": false,
  "error": {
    "code": "DUPLICATE_SCHEMA",
    "message": "A schema with this name and version already exists"
  }
}
```

## Best Practices

<AccordionGroup>
  <Accordion icon="tag" title="Versioning">
    * Use semantic versioning (1.0.0, 1.1.0, 2.0.0)
    * Increment major version for breaking changes
    * Increment minor version for new fields
    * Increment patch version for description updates
  </Accordion>

  <Accordion icon="file-lines" title="Documentation">
    * Provide clear descriptions for each field
    * Include examples for complex field types
    * Document any business rules or constraints
    * Explain the source of the data
  </Accordion>

  <Accordion icon="shield-check" title="Validation">
    * Always set required: true for mandatory fields
    * Use constraints to enforce data quality
    * Validate email formats with regex patterns
    * Set reasonable min/max values for numbers
  </Accordion>

  <Accordion icon="users" title="Sharing">
    * Mark common schemas as public for organization-wide use
    * Keep sensitive schemas private
    * Document any dependencies between schemas
    * Coordinate schema updates with your team
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Create Field Mappings" icon="arrows-left-right" href="/api-reference/data-ingestion/field-mappings">
    Map your schema fields to gu1's entity model
  </Card>

  <Card title="Smart Field Detection" icon="wand-magic-sparkles" href="/api-reference/data-ingestion/custom-schemas">
    Auto-detect field types from sample data
  </Card>

  <Card title="Import Entities" icon="upload" href="/en/api-reference/bulk-imports/import-entities">
    Use your schema to bulk import entities
  </Card>

  <Card title="Data Mapping Guide" icon="book" href="/api-reference/data-ingestion/overview">
    Complete guide to data mapping workflows
  </Card>
</CardGroup>
