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

# Get a model

> One model's context window, price, and whether it is enabled. Skip the prefix filter and fetch it directly.

Read one model. When you already know which one you want, this is faster and more exact than filtering [the list](/docs/api-reference/modelservice/list-models).

<CodeGroup>
  ```typescript TypeScript theme={null}
  const model = await client.models.retrieve('external_id:claude-sonnet-4-6', { workspaceId });

  console.log(model.spec.maxInputTokens);              // 1000000
  console.log(model.spec.inputPricePerMillionTokens);  // '300'  (cents, $3.00)
  console.log(model.state);                            // 'STATE_ENABLED'
  ```

  ```go Go theme={null}
  model, err := client.Models.Get(ctx, "external_id:claude-sonnet-4-6", cadenya.ModelGetParams{
  	WorkspaceID: cadenya.String(workspaceID),
  })

  fmt.Println(model.Spec.MaxInputTokens)             // 1000000
  fmt.Println(model.Spec.InputPricePerMillionTokens) // '300'  (cents, $3.00)
  fmt.Println(model.State)                           // 'STATE_ENABLED'
  ```

  ```ruby Ruby theme={null}
  model = cadenya.models.retrieve("external_id:claude-sonnet-4-6", workspace_id: workspace_id)

  puts model.spec.max_input_tokens                # 1000000
  puts model.spec.input_price_per_million_tokens  # '300'  (cents, $3.00)
  puts model.state                                # 'STATE_ENABLED'
  ```

  ```bash cURL theme={null}
  curl "https://api.cadenya.com/v1/workspaces/${WORKSPACE_ID}/models/external_id:claude-sonnet-4-6" \
    -H "Authorization: Bearer ${CADENYA_API_KEY}"
  ```
</CodeGroup>

The `external_id:` form is the one to use, since it is also what you set on a variation's `modelConfig.modelId`. The canonical `model_...` ID works too. A missing ID is a `404`.

## What the record holds

| Field                              | Meaning                                                                    |
| ---------------------------------- | -------------------------------------------------------------------------- |
| `metadata.externalId`              | The stable slug, `claude-sonnet-4-6`                                       |
| `spec.provider`                    | `anthropic`, `openai`                                                      |
| `spec.family`                      | `claude-sonnet`, `gpt`                                                     |
| `spec.maxInputTokens`              | Context window. What `compactionConfig.triggerThreshold` is a fraction of. |
| `spec.maxOutputTokens`             | Per-response ceiling                                                       |
| `spec.inputPricePerMillionTokens`  | Cents per million tokens, as a string                                      |
| `spec.outputPricePerMillionTokens` | Cents per million tokens, as a string                                      |
| `state`                            | `STATE_ENABLED` or `STATE_DISABLED`                                        |

The [list-models page](/docs/api-reference/modelservice/list-models) explains the two traps in full: prices are integer cents serialized as strings (parse, then divide by 100 to render), and `maxInputTokens` is what a variation's compaction threshold is measured against, so it moves when you swap models.

`state` matters before you point a variation at the model. A [disabled](/docs/api-reference/modelservice/disable-a-model) model is a `400` on `spec.model_id`, so read it here first if a variation create is failing on the model.

## Related

<CardGroup cols={2}>
  <Card title="List models" icon="microchip" href="/docs/api-reference/modelservice/list-models">
    Every model, and the pricing and compaction details in full.
  </Card>

  <Card title="Create a variation" icon="sliders" href="/docs/api-reference/agentvariationservice/create-a-new-variation">
    Where `modelConfig.modelId` takes the `external_id:` form.
  </Card>

  <Card title="Swap models on variations" icon="right-left" href="/docs/api-reference/modelservice/swap-models-on-agent-variations">
    Move a whole workspace off a model.
  </Card>
</CardGroup>


## OpenAPI

````yaml get /v1/workspaces/{workspaceId}/models/{id}
openapi: 3.1.0
info:
  title: Cadenya API
  description: API for the Cadenya Agent Runtime platform.
  version: '1.0'
servers:
  - url: https://api.cadenya.com
    description: Production server
security:
  - bearerAuth: []
tags:
  - name: AIProviderKeyService
  - name: APIKeyService
    description: |-
      Issue, rotate, disable, and revoke a workspace's API keys. Every key
       belongs to exactly one workspace; the system-managed global account key is
       managed via GlobalAPIKeyService instead.
  - name: AccountService
    description: >-
      Manage the authenticated account. Accounts are the top-level
      organizational
       unit and contain one or more workspaces.
  - name: AgentScheduleService
    description: >-
      Manage recurring schedules attached to agents. Schedules trigger
      objectives
       on a cadence defined by AgentScheduleSpec.Schedule.
  - name: AgentService
    description: >-
      Manage AI agents within a workspace. Agents define AI behavior and tool
      access.
  - name: AgentVariationService
    description: >-
      Manage variations of an agent and their tool, sub-agent, and memory layer
      assignments.
  - name: GlobalAPIKeyService
    description: |-
      Manage the account's system-provisioned global API key. The global key is
       the only key that spans every workspace; it is created by the system and
       cannot be deleted, so the surface is retrieve, rotate, and the
       disable/enable kill switch.
  - name: MemoryService
    description: >-
      Manage memory layers and their entries. Layers are named containers that
      can
       be composed into an objective's memory cascade; entries are the keyed values
       within a layer. System-managed layers (e.g., episodic layers created by the
       runtime) cannot be mutated through this API.
  - name: ModelService
    description: |-
      Manage LLM models available to a workspace. Models represent provider and
       family pairs (e.g., "anthropic/claude-sonnet-4.6"). Workspaces are seeded
       with the supported models and you can enable or disable each one.
  - name: ObjectiveEventStreamsService
  - name: ObjectiveService
  - name: ProfilesService
    description: |-
      Operations on profiles, the account-level principals (users, API keys,
       system) that authenticate against the API.
  - name: SearchService
  - name: TenantService
    description: >-
      Read and erase tenants and the subjects under them. Tenants and subjects
      are
       created by assertion — on objective creation or widget session mint — never
       directly, so this service has no create or update: it exists to enumerate what
       assertions have produced, and to destroy it on request.
  - name: ToolService
    description: >-
      Manage tool sets and the tools they contain. Tool sets group related
      tools,
       and tools define specific capabilities available to agents.

       When a tool set is managed, only API key actors can modify its tools; human
       (profile) actors cannot.
  - name: UploadService
    description: |-
      Issue short-lived presigned URLs for direct client-to-object-storage
       uploads. Created uploads can be referenced by id when creating or updating
       resources that accept binary content (e.g., MemoryEntry).
  - name: WidgetService
    description: |-
      Manage embeddable chat widgets. A widget binds an agent to a globally
       unique hostname with a per-widget origin allowlist; browsers reach it with
       session tokens minted via WidgetSessionService.
  - name: WidgetSessionService
    description: >-
      Mint and manage widget sessions. Session creation is server-to-server
      only:
       the customer's backend authenticates its visitor, asserts tenant/subject
       context, attaches any per-visitor secrets, and receives a short-lived
       bearer token the browser uses against the widget host.
  - name: WorkspaceAdminService
    description: >-
      Administer workspaces across the account: create and archive workspaces
      and
       manage their membership. These operations are account-scoped and require the
       admin role (a token whose profile holds the WorkOS admin role); they live
       under /v1/account/workspaces rather than the workspace-scoped /v1/workspaces
       tree so an admin can manage any workspace in the account, including ones they
       are not themselves a member of.
  - name: WorkspaceSecretService
  - name: WorkspaceService
    description: |-
      Manage workspaces within an account. Workspaces provide organizational
       grouping and isolation for resources such as agents, tools, and API keys.

       This is the workspace-scoped, end-user surface. Administrative operations
       (create / archive workspaces, manage members) live in WorkspaceAdminService
       under /v1/account/workspaces and require the admin role.
paths:
  /v1/workspaces/{workspaceId}/models/{id}:
    get:
      tags:
        - ModelService
        - Models
      summary: Get a model by ID
      description: Retrieves a model by ID from the workspace
      operationId: ModelService_GetModel
      parameters:
        - name: workspaceId
          in: path
          description: Workspace ID.
          required: true
          schema:
            type: string
            example: workspace_01HXKD2E5NQM3T9AYWCF133E3Q
        - name: id
          in: path
          description: Model ID
          required: true
          schema:
            type: string
            example: model_01HXKD2E5NQM3T9AYWCFKJ4GED
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Model'
        default:
          description: Default error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Status'
      x-codeSamples:
        - lang: JavaScript
          source: >-
            import Cadenya from '@cadenya/cadenya';


            const client = new Cadenya({
              apiKey: process.env['CADENYA_API_KEY'], // This is the default and can be omitted
            });


            const model = await
            client.models.retrieve('model_01HXKD2E5NQM3T9AYWCFKJ4GED', {
              workspaceId: 'workspace_01HXKD2E5NQM3T9AYWCF133E3Q',
            });


            console.log(model.metadata);
        - lang: Python
          source: |-
            import os
            from cadenya import Cadenya

            client = Cadenya(
                api_key=os.environ.get("CADENYA_API_KEY"),  # This is the default and can be omitted
            )
            model = client.models.retrieve(
                id="model_01HXKD2E5NQM3T9AYWCFKJ4GED",
                workspace_id="workspace_01HXKD2E5NQM3T9AYWCF133E3Q",
            )
            print(model.metadata)
        - lang: Go
          source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"go.cadenya.com/cadenya-go\"\n\t\"go.cadenya.com/cadenya-go/option\"\n)\n\nfunc main() {\n\tclient := cadenya.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tmodel, err := client.Models.Get(\n\t\tcontext.TODO(),\n\t\t\"model_01HXKD2E5NQM3T9AYWCFKJ4GED\",\n\t\tcadenya.ModelGetParams{\n\t\t\tWorkspaceID: cadenya.String(\"workspace_01HXKD2E5NQM3T9AYWCF133E3Q\"),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", model.Metadata)\n}\n"
        - lang: Ruby
          source: |-
            require "cadenya"

            cadenya = Cadenya::Client.new(api_key: "My API Key")

            model = cadenya.models.retrieve(
              "model_01HXKD2E5NQM3T9AYWCFKJ4GED",
              workspace_id: "workspace_01HXKD2E5NQM3T9AYWCF133E3Q"
            )

            puts(model)
        - lang: CLI
          source: |-
            cadenya models retrieve \
              --api-key 'My API Key' \
              --workspace-id workspace_01HXKD2E5NQM3T9AYWCF133E3Q \
              --id model_01HXKD2E5NQM3T9AYWCFKJ4GED
components:
  schemas:
    Model:
      required:
        - metadata
        - spec
        - state
      type: object
      properties:
        metadata:
          allOf:
            - $ref: '#/components/schemas/ResourceMetadata'
          description: Resource metadata
        spec:
          allOf:
            - $ref: '#/components/schemas/ModelSpec'
          description: Model specification
        info:
          readOnly: true
          allOf:
            - $ref: '#/components/schemas/ModelInfo'
          description: >-
            Server-populated info (e.g. the AI provider this model routes
            through).
             Populated on reads when requested; see ListModelsRequest.include_info.
        state:
          readOnly: true
          enum:
            - STATE_UNSPECIFIED
            - STATE_ENABLED
            - STATE_DISABLED
          type: string
          description: |-
            Whether the model is usable in this workspace. Output only. Use the
             :enable and :disable actions to transition.
          format: enum
    Status:
      type: object
      properties:
        code:
          type: integer
          description: >-
            The status code, which should be an enum value of
            [google.rpc.Code][google.rpc.Code].
          format: int32
        message:
          type: string
          description: >-
            A developer-facing error message, which should be in English. Any
            user-facing error message should be localized and sent in the
            [google.rpc.Status.details][google.rpc.Status.details] field, or
            localized by the client.
        details:
          type: array
          items:
            $ref: '#/components/schemas/GoogleProtobufAny'
          description: >-
            A list of messages that carry the error details.  There is a common
            set of message types for APIs to use.
      description: >-
        The `Status` type defines a logical error model that is suitable for
        different programming environments, including REST APIs and RPC APIs. It
        is used by [gRPC](https://github.com/grpc). Each `Status` message
        contains three pieces of data: error code, error message, and error
        details. You can find out more about this error model and how to work
        with it in the [API Design
        Guide](https://cloud.google.com/apis/design/errors).
    ResourceMetadata:
      required:
        - id
        - accountId
        - workspaceId
        - name
        - profileId
        - createdAt
      type: object
      properties:
        id:
          readOnly: true
          type: string
          description: >-
            Unique identifier for the resource (prefixed ULID, e.g.,
            "agent_01HXK...")
        accountId:
          readOnly: true
          example: account_01HXKD2E5NQM3T9AYWCFTJHJVF
          type: string
          description: >-
            Account this resource belongs to for multi-tenant isolation
            (prefixed ULID)
        workspaceId:
          readOnly: true
          example: workspace_01HXKD2E5NQM3T9AYWCF133E3Q
          type: string
          description: >-
            Workspace this resource belongs to for organizational grouping
            (prefixed ULID)
        name:
          type: string
          description: >-
            Human-readable name for the resource (e.g., "Customer Support
            Agent", "Email Tool")
             Required for resources that users interact with directly
        externalId:
          type: string
          description: >-
            External ID for the resource (e.g., a workflow ID from an external
            system)
        labels:
          type: object
          additionalProperties:
            type: string
          description: |-
            Key-value pairs for categorization and filtering. Values are 0-63
             alphanumeric characters with "-", "_", or "." allowed between; keys
             follow the same shape and additionally accept an optional DNS-subdomain
             prefix (e.g. "cadenya.com/") of at most 253 characters.
             Examples: {"environment": "production", "team": "platform", "version": "v2"}
        profileId:
          readOnly: true
          example: profile_01HXKD2E5NQM3T9AYWCFS0AP08
          type: string
          description: ID of the actor (user or service account) that created this resource
        createdAt:
          readOnly: true
          type: string
          description: Timestamp when this resource was created
          format: date-time
        updatedAt:
          readOnly: true
          type: string
          description: Timestamp when this resource was last updated
          format: date-time
      description: >-
        Standard metadata for persistent, named resources (e.g., agents, tools,
        prompts)
    ModelSpec:
      required:
        - provider
        - family
      type: object
      properties:
        provider:
          type: string
          description: The model provider (e.g., "anthropic", "openai", "google")
        family:
          type: string
          description: >-
            The model family (e.g., "claude-sonnet-4.6", "gpt-5.4",
            "gemini-2.5-flash")
        maxInputTokens:
          type: integer
          description: Maximum number of input tokens the model supports
          format: int32
        maxOutputTokens:
          type: integer
          description: Maximum number of output tokens the model can generate
          format: int32
        inputPricePerMillionTokens:
          type: string
          description: Cost per million input tokens in cents (e.g., 300 = $3.00)
        outputPricePerMillionTokens:
          type: string
          description: Cost per million output tokens in cents (e.g., 1500 = $15.00)
    ModelInfo:
      type: object
      properties:
        aiProviderKey:
          readOnly: true
          allOf:
            - $ref: '#/components/schemas/AIProviderKey'
          description: >-
            The AI provider key powering this model, embedded so clients can
            read the
             provider, key name, and promotional status (info.is_promotional) without a
             second lookup. The key's model counts are not populated here; use the AI
             provider key endpoints for those.
        agentVariationCount:
          readOnly: true
          type: integer
          description: >-
            Number of agent variations currently provisioned on this model.
            Useful for
             previewing how many variations a swap would affect.
          format: int32
        lastUsedAt:
          readOnly: true
          type: string
          description: Represents the last time this model was used in an agent objective
          format: date-time
      description: ModelInfo carries server-derived, read-only details about a model.
    GoogleProtobufAny:
      type: object
      properties:
        '@type':
          type: string
          description: The type of the serialized message.
      additionalProperties: true
      description: >-
        Contains an arbitrary serialized message along with a @type that
        describes the type of the serialized message.
    AIProviderKey:
      required:
        - metadata
        - spec
      type: object
      properties:
        metadata:
          $ref: '#/components/schemas/ResourceMetadata'
        spec:
          $ref: '#/components/schemas/AIProviderKeySpec'
        info:
          readOnly: true
          allOf:
            - $ref: '#/components/schemas/AIProviderKeyInfo'
          description: |-
            Server-populated info (e.g. how many models route through this key).
             Populated on reads when requested; see ListAIProviderKeysRequest.include_info.
      description: |-
        AIProviderKey is a credential for an AI provider, scoped to a workspace.
         Most keys are customer-provided (BYOK); Cadenya also provisions promotional
         keys (see AIProviderKeyInfo.is_promotional), which cannot be modified or
         deleted by account administrators. The secret value is never returned in
         responses.
    AIProviderKeySpec:
      type: object
      properties:
        provider:
          enum:
            - AI_PROVIDER_UNSPECIFIED
            - AI_PROVIDER_OPENROUTER
            - AI_PROVIDER_OPENAI
            - AI_PROVIDER_ANTHROPIC
            - AI_PROVIDER_GEMINI
            - AI_PROVIDER_OPENAI_COMPATIBLE
          type: string
          description: The AI provider this key authenticates against.
          format: enum
        credentials:
          allOf:
            - $ref: '#/components/schemas/AIProviderCredential'
          description: >-
            The provider credential. Accepted on create/update; never populated
            in
             responses (the server returns an empty value to avoid leaking the secret).
        config:
          allOf:
            - $ref: '#/components/schemas/AIProviderConfig'
          description: >-
            Non-secret, provider-specific settings (OpenAI org/project,
            OpenRouter
             region, OpenAI-compatible base URL). The set case must correspond to
             `provider`. Returned on reads. Optional: omit to accept provider defaults.
    AIProviderKeyInfo:
      type: object
      properties:
        enabledModelCount:
          readOnly: true
          type: integer
          description: Number of enabled models provisioned on this key.
          format: int32
        disabledModelCount:
          readOnly: true
          type: integer
          description: Number of disabled models provisioned on this key.
          format: int32
        isPromotional:
          readOnly: true
          type: boolean
          description: >-
            Cadenya includes promotional keys (one for onboarding, and
            potentially more in the future).
             These are not added or maintained by account administrators.
      description: >-
        AIProviderKeyInfo carries server-derived, read-only details about a key,
        for
         AI provider management UIs.
    AIProviderCredential:
      oneOf:
        - $ref: '#/components/schemas/AIProviderCredential_ApiKey'
        - $ref: '#/components/schemas/AIProviderCredential_Headers'
      discriminator:
        propertyName: type
        mapping:
          apiKey:
            $ref: '#/components/schemas/AIProviderCredential_ApiKey'
          headers:
            $ref: '#/components/schemas/AIProviderCredential_Headers'
      description: |-
        AIProviderCredential is the secret material used to authenticate with a
         provider. The set case must correspond to AIProviderKeySpec.provider. The
         server encrypts the serialized message at rest and never returns it on reads.
    AIProviderConfig:
      oneOf:
        - $ref: '#/components/schemas/AIProviderConfig_Openrouter'
        - $ref: '#/components/schemas/AIProviderConfig_Openai'
        - $ref: '#/components/schemas/AIProviderConfig_OpenaiCompatible'
      discriminator:
        propertyName: type
        mapping:
          openrouter:
            $ref: '#/components/schemas/AIProviderConfig_Openrouter'
          openai:
            $ref: '#/components/schemas/AIProviderConfig_Openai'
          openaiCompatible:
            $ref: '#/components/schemas/AIProviderConfig_OpenaiCompatible'
      description: >-
        AIProviderConfig holds non-secret, provider-specific settings. The set
        case
         must correspond to AIProviderKeySpec.provider. Providers with no settings
         (Anthropic, Gemini) simply leave this unset. The endpoint of a named provider
         is fixed and intentionally not overridable here; use the OpenAI-compatible
         provider to target a custom endpoint.
    AIProviderCredential_ApiKey:
      type: object
      required:
        - type
        - apiKey
      properties:
        type:
          type: string
          enum:
            - apiKey
        apiKey:
          allOf:
            - $ref: '#/components/schemas/CredentialAPIKey'
          description: >-
            Single API key (OpenRouter, OpenAI, Anthropic, Gemini, and most
            others).
    AIProviderCredential_Headers:
      type: object
      required:
        - type
        - headers
      properties:
        type:
          type: string
          enum:
            - headers
        headers:
          allOf:
            - $ref: '#/components/schemas/CredentialHeaders'
          description: >-
            Arbitrary auth headers, for generic endpoints that authenticate with
            a
             custom header rather than a bearer key (pairs with the OpenAI-compatible
             provider).
    AIProviderConfig_Openrouter:
      type: object
      required:
        - type
        - openrouter
      properties:
        type:
          type: string
          enum:
            - openrouter
        openrouter:
          $ref: '#/components/schemas/OpenRouterConfig'
    AIProviderConfig_Openai:
      type: object
      required:
        - type
        - openai
      properties:
        type:
          type: string
          enum:
            - openai
        openai:
          $ref: '#/components/schemas/OpenAIConfig'
    AIProviderConfig_OpenaiCompatible:
      type: object
      required:
        - type
        - openaiCompatible
      properties:
        type:
          type: string
          enum:
            - openaiCompatible
        openaiCompatible:
          $ref: '#/components/schemas/OpenAICompatibleConfig'
    CredentialAPIKey:
      type: object
      properties:
        apiKey:
          type: string
      description: CredentialAPIKey carries a single bearer/header API key.
    CredentialHeaders:
      type: object
      properties:
        headers:
          type: object
          additionalProperties:
            type: string
      description: >-
        CredentialHeaders carries arbitrary HTTP headers sent with every request
        to
         the provider (e.g. {"Authorization": "Bearer ...", "X-Api-Key": "..."}).
    OpenRouterConfig:
      type: object
      properties:
        region:
          type: string
          description: >-
            Data-residency region (e.g. "us", "eu"). Empty uses the provider
            default.
      description: OpenRouterConfig holds OpenRouter-specific settings.
    OpenAIConfig:
      type: object
      properties:
        organizationId:
          type: string
          description: Sent as the OpenAI-Organization header when set.
        projectId:
          type: string
          description: Sent as the OpenAI-Project header when set.
      description: OpenAIConfig holds OpenAI-specific settings.
    OpenAICompatibleConfig:
      required:
        - baseUrl
      type: object
      properties:
        baseUrl:
          type: string
      description: >-
        OpenAICompatibleConfig configures a generic endpoint that speaks the
        OpenAI
         Chat Completions API. The base URL is required and its model catalog is
         discovered live via GET {base_url}/models.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````