# `PhoenixKitAI.Endpoint`
[🔗](https://github.com/BeamLabEU/phoenix_kit_ai/blob/v0.4.0/lib/phoenix_kit_ai/endpoint.ex#L1)

AI endpoint schema for PhoenixKit AI system.

An endpoint is a unified configuration that combines provider credentials,
model selection, and generation parameters into a single entity. Each endpoint
represents one complete AI configuration ready for making API requests.

## Schema Fields

### Identity
- `name`: Display name for the endpoint (e.g., "Claude Fast", "GPT-4 Creative")
- `description`: Optional description of the endpoint's purpose

### Provider Configuration
- `provider`: Integration connection key (e.g. `"openrouter"` or
  `"openrouter:my-key"`). Resolved via `PhoenixKit.Integrations`.
- `api_key`: **Deprecated.** Legacy field retained for pre-Integrations
  endpoints — `OpenRouterClient.resolve_api_key/2` reads it as a fallback
  when no `PhoenixKit.Integrations` connection is configured for the
  endpoint's `provider`. The column is `NOT NULL` in core's V34
  migration, so for now you must provide a value (an empty string is
  accepted by the DB but will trigger a per-call `Logger.warning`
  if no Integrations connection is set up either). The recommended
  migration path is documented in `AGENTS.md` "Migrating from legacy
  `endpoint.api_key`" — set up an OpenRouter connection under Settings
  → Integrations and point `provider` at it; the legacy column then
  becomes unused. Planned for removal in a future major version once
  operators have had time to migrate.
- `base_url`: Optional custom base URL for the provider
- `provider_settings`: Provider-specific settings (JSON)
  - For OpenRouter: `http_referer`, `x_title` headers

### Model Configuration
- `model`: AI model identifier (e.g., "anthropic/claude-3-haiku")

### Generation Parameters
- `temperature`: Sampling temperature (0-2, default: 0.7)
- `max_tokens`: Maximum tokens to generate (nil = model default)
- `top_p`: Nucleus sampling threshold (0-1)
- `top_k`: Top-k sampling parameter
- `frequency_penalty`: Frequency penalty (-2 to 2)
- `presence_penalty`: Presence penalty (-2 to 2)
- `repetition_penalty`: Repetition penalty (0-2)
- `stop`: Stop sequences (array of strings)
- `seed`: Random seed for reproducibility

### Image Generation Parameters
- `image_size`: Image size (e.g., "1024x1024", "1792x1024")
- `image_quality`: Image quality ("standard", "hd")

### Embeddings Parameters
- `dimensions`: Embedding dimensions (model-specific)

### Status
- `enabled`: Whether the endpoint is active
- `sort_order`: Display order for listing
- `last_validated_at`: Last successful API key validation

## Usage Examples

    # Create an endpoint
    {:ok, endpoint} = PhoenixKitAI.create_endpoint(%{
      name: "Claude Fast",
      provider: "openrouter",
      api_key: "sk-or-v1-...",
      model: "anthropic/claude-3-haiku",
      temperature: 0.7
    })

    # Use the endpoint
    {:ok, response} = PhoenixKitAI.ask(endpoint.uuid, "Hello!")

# `t`

```elixir
@type t() :: %PhoenixKitAI.Endpoint{
  __meta__: term(),
  api_key: term(),
  base_url: term(),
  description: term(),
  dimensions: term(),
  enabled: term(),
  frequency_penalty: term(),
  image_quality: term(),
  image_size: term(),
  inserted_at: term(),
  integration_uuid: term(),
  last_validated_at: term(),
  max_tokens: term(),
  model: term(),
  name: term(),
  presence_penalty: term(),
  provider: term(),
  provider_settings: term(),
  reasoning_effort: term(),
  reasoning_enabled: term(),
  reasoning_exclude: term(),
  reasoning_max_tokens: term(),
  repetition_penalty: term(),
  requests: term(),
  seed: term(),
  sort_order: term(),
  stop: term(),
  temperature: term(),
  top_k: term(),
  top_p: term(),
  updated_at: term(),
  uuid: term()
}
```

# `changeset`

Creates a changeset for endpoint creation and updates.

# `default_base_url`

```elixir
@spec default_base_url(String.t()) :: String.t() | nil
```

Returns the default base URL for a provider.

All three current providers expose an OpenAI-compatible chat
completions endpoint at `<base>/chat/completions`, so the same
Completion HTTP layer works for them.

# `image_quality_options`

Returns image quality options for form selects.

# `image_size_options`

Returns image size options for form selects.

# `masked_api_key`

```elixir
@spec masked_api_key(String.t() | nil) :: String.t()
```

Masks the API key for display.

- `nil` or `""` → `"Not set"`.
- Keys shorter than 14 chars → `"•••"` (a 13-char key would otherwise
  leak most of itself with the head+tail shape).
- Longer keys → first 8 + `…` + last 4 (e.g. `"sk-or-v1…mnop"`).
  Recognisable provider prefix retained, identifying suffix retained,
  middle elided. Useful for human-recognition in admin cards while
  still hiding the bulk of the secret.

# `provider_label`

```elixir
@spec provider_label(String.t()) :: String.t()
```

Returns a display label for the provider.

Brand names stay un-translated by design — `"OpenRouter"`,
`"Mistral"`, `"DeepSeek"` are product trademarks, not user-facing
prose. Translating them would produce `"OpenRouter Соединение"` /
`"OpenRouter Verbindung"` style mixed strings that read worse
than the bilingual label they replace. The surrounding word
(`"Connection"` in the form's section header) IS gettext-wrapped
separately so the operator's locale picks up the localised
connector word; the brand stays the brand.

# `provider_options`

```elixir
@spec provider_options() :: [{String.t(), String.t()}]
```

Returns provider options for form selects.

# `reasoning_effort_options`

Returns reasoning effort options for form selects.

# `recently_validated?`

Checks if the endpoint has been validated recently (within the last 24 hours).

# `short_model_name`

Extracts the model name without the provider prefix.

# `valid_providers`

```elixir
@spec valid_providers() :: [String.t()]
```

Returns the list of valid provider types.

# `validation_changeset`

Creates a changeset for updating the last_validated_at timestamp.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
