---
title: "Update an identity"
method: PATCH
path: "/v2/identities/{id}"
tags: ["Identities"]
---

# Update an identity

`PATCH /v2/identities/{id}`

Updates specific fields of an existing identity. Only the fields provided in the request body will be updated.

## Path parameters

- `id` string, required

## Request body

- UpdateIdentityRequest
  - `display_name` string — New display name. Omit to keep the current display name.
  - `email` string — New email address. Omit to keep the current email.
  - `avatar_url` string — New avatar image URL. Omit to keep the current avatar URL.
  - `tags` string[] — Replacement tag list. Leave empty to clear tags.
  - `metadata` object — Replacement custom JSON metadata.

## Response `200`

OK

- UpdateIdentityResponse
  - `identity` Identity, required
    - `_id` string, required — Unique identity identifier assigned by ORQ. Returned as `_id` for compatibility with the v1 identity API.
    - `external_id` string, required — Customer-provided stable identifier for this identity. This value is required on create and is unique within the workspace.
    - `workspace_id` string, required — Workspace that owns the identity.
    - `display_name` string — Human-readable display name for the identity.
    - `email` string — Email address associated with the identity.
    - `avatar_url` string — URL of the identity avatar image.
    - `tags` string[] — Free-form labels used to organize and filter identities.
    - `metadata` object — Custom JSON metadata stored with the identity.
    - `created` string, required — ISO timestamp for when the identity was created.
    - `updated` string, required — ISO timestamp for when the identity was last updated.
    - `metrics` IdentityMetrics
      - `total_tokens` number, double, required — Total token count attributed to the identity.
      - `total_cost` number, double, required — Total cost attributed to the identity.
      - `total_requests` number, double, required — Total request count attributed to the identity.
      - `error_rate` number, double, required — Fraction of attributed requests that failed.
    - `budget` Budget — Budget is the canonical record stored in MongoDB `budgets.entities`. It replaces the embedded `constraints.budget` on api-keys and the legacy CONTACT-only `budgets.configs` collection (see ADR 0007).
      - `budget_id` string, required
      - `scope` BudgetScope — BudgetScope is a closed oneof. Exactly one variant must be set. The six variants are ordered by enforcement precedence (most specific to most general) and mirror the BudgetScopeKind filter enum.
        - `workspace` WorkspaceBudgetScope — Workspace-wide ceiling. The implicit target is the caller's workspace.
        - `project` ProjectBudgetScope — Per-project cap.
          - `project_id` string
        - `identity` IdentityBudgetScope — Per-identity cap. Keyed by the contact's external_id (not the internal Mongo `_id`) so the scope is stable across imports.
          - `identity_external_id` string
        - `api_key` ApiKeyBudgetScope — Per-api-key cap. Replaces the legacy embedded `constraints.budget` on auth.apiKeys.
          - `api_key_id` string
        - `provider` ProviderBudgetScope — Per-provider cap. The value is the provider enum string (e.g. "openai", "anthropic") drawn from ModelIntegrationIdentifier.
          - `provider` string
        - `model` ModelBudgetScope — Per-model cap. The value is the FULL model reference as callers send it ("openai/gpt-4o", or "workspaceKey@openai/gpt-4o" for private models) — NOT the Mongo `_id` of the model master-data document.
          - `model_id` string, required
      - `match` BudgetMatch — BudgetMatch carries the CEL expression that decides whether a budget applies to a request. Available variables: `model`, `provider`, `model_id`, `api_key`, `identity`, `project`, `metadata` (map), `headers` (map, lowercase keys). An empty expression always matches. Expressions are syntax-validated at write time.
        - `cel` string
      - `limits` BudgetLimits, required — BudgetLimits is the per-period spend and token ceiling. At least one of `amount`, `token_limit`, or RateLimit.requests_per_minute MUST be set on a Budget; that invariant is enforced by the handler.
        - `period` 'BUDGET_PERIOD_UNSPECIFIED' | 'BUDGET_PERIOD_DAILY' | 'BUDGET_PERIOD_WEEKLY' | 'BUDGET_PERIOD_MONTHLY' | 'BUDGET_PERIOD_YEARLY' | 'BUDGET_PERIOD_ONE_TIME'
        - `amount` number, double
        - `token_limit` number, double — Token ceiling. Carried as a double so it serializes as a JSON number (proto int64 would serialize as a quoted string); token counts are whole and well within double's exact-integer range (2^53). Stored as an integer server-side.
      - `rate_limit` RateLimit — RateLimit is the per-minute request ceiling. Enforced via atomic increment-first semantics in the enforcement middleware.
        - `requests_per_minute` integer
      - `is_active` boolean
      - `expires_at` string, date-time
      - `created_at` string, date-time, required
      - `updated_at` string, date-time, required
      - `usage` BudgetUsage — BudgetUsage is the current-period consumption of a budget, sourced from the live Redis counters (not the exact ledger). Each dimension is the consumed side of the matching limit dimension: `amount` is the accumulated cost in USD (vs limits.amount), `tokens` is the accumulated token count (vs limits.token_limit), and `requests` is the count in the rolling 60-second window (vs rate_limit.requests_per_minute). All three are explicit-presence so the triple is always emitted in full, zeros included — a never-spent budget serializes {amount:0, tokens:0, requests:0} rather than dropping its zero dimensions.
        - `amount` number, double
        - `tokens` number, double — Carried as a double (not int64) so it serializes as a JSON number rather than a quoted string, matching limits.token_limit.
        - `requests` integer
      - `alerts` BudgetAlert[] — Threshold notifications. Absent when the budget has none.
        - `id` string — Assigned by ORQ. Supply an existing id to edit that alert in place.
        - `threshold_percent` integer, required — Percentage of the dimension's limit at which the alert fires, 1–100.
        - `notifier_ids` string[], required — Must be workspace-scoped; project-scoped notifiers are rejected.
        - `dimension` 'BUDGET_ALERT_DIMENSION_UNSPECIFIED' | 'BUDGET_ALERT_DIMENSION_COST' | 'BUDGET_ALERT_DIMENSION_TOKENS'

---

[API](https://skmtc.net/orq-ai/apis/orq-ai-api.md) · [All operations](https://skmtc.net/orq-ai/apis/orq-ai-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/orq-ai/orq-ai-api/versions/41c02aedc7c0/schema)
