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

# Create a team via Admin API



## OpenAPI

````yaml /api-reference/openapi.json post /terraform/teams
openapi: 3.0.0
info:
  title: Costory
  version: '1.0'
  description: API Documentation
servers:
  - url: https://app-api.costory.io
security: []
paths:
  /terraform/teams:
    post:
      tags:
        - Admin Teams
      summary: Create a team via Admin API
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                description:
                  type: string
                  default: ''
                visibility:
                  type: string
                  enum:
                    - PUBLIC
                    - PRIVATE
                defaultCostMetric:
                  type: string
                  enum:
                    - cost
                    - effective_cost
                    - list_cost
                    - contracted_cost
                    - unblended_cost
                    - net_unblended_cost
                    - amortized_cost
                    - net_amortized_cost
                scope:
                  type: string
                  description: >-
                    Optional team cost filter as CEL. When set, parses and
                    validates against organization dimensions, then persists as
                    whereClause. On create, writes the initial Default scope. On
                    update, updates the single scope row; if the team has more
                    than one named scope, use the /scopes API instead.
              required:
                - name
      responses:
        '201':
          description: Created team
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminTeamWithMembers'
        '400':
          description: >-
            Bad request (e.g. validation). When the team name is already taken,
            error is TEAM_NAME_EXISTS and existingTeamId is set. When `scope`
            CEL is invalid, error is INVALID_SCOPE_FILTER with a reason.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TerraformTeamPatchBadRequest'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Unauthorized'
      security:
        - bearerAuth: []
        - apiKeyAuth: []
components:
  schemas:
    AdminTeamWithMembers:
      type: object
      properties:
        id:
          type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        archivedAt:
          type: string
          nullable: true
          format: date-time
        name:
          type: string
        description:
          type: string
        visibility:
          type: string
          enum:
            - PUBLIC
            - PRIVATE
        defaultCostMetric:
          type: string
          enum:
            - cost
            - effective_cost
            - list_cost
            - contracted_cost
            - unblended_cost
            - net_unblended_cost
            - amortized_cost
            - net_amortized_cost
        organizationId:
          type: string
        scopes:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
                description: Scope row id.
              name:
                type: string
                description: Human-readable scope name.
              whereClause:
                type: object
                properties: {}
                additionalProperties: {}
                description: >-
                  Persisted react-querybuilder filter (RuleGroupType). Canonical
                  filter string for API clients is filterCel.
              filterCel:
                type: string
                description: >-
                  Team cost filter as CEL (Common Expression Language), derived
                  from whereClause.
            required:
              - id
              - name
              - whereClause
              - filterCel
        _count:
          type: object
          properties:
            members:
              type: number
          required:
            - members
        members:
          type: array
          items:
            type: object
            properties:
              role:
                type: string
                enum:
                  - OWNER
                  - MEMBER
            required:
              - role
      required:
        - id
        - createdAt
        - updatedAt
        - name
        - description
        - visibility
        - defaultCostMetric
        - organizationId
        - scopes
        - _count
        - members
    TerraformTeamPatchBadRequest:
      anyOf:
        - $ref: '#/components/schemas/BadRequest'
        - $ref: '#/components/schemas/TeamNameExists'
        - $ref: '#/components/schemas/TerraformTeamInvalidScopeFilter'
        - $ref: '#/components/schemas/TerraformTeamMultipleScopes'
        - $ref: '#/components/schemas/TerraformTeamOrgContextRequired'
    Unauthorized:
      type: object
      properties:
        error:
          type: string
          description: Unauthorized error message
      required:
        - error
    BadRequest:
      type: object
      properties:
        error:
          type: string
          description: Error code
        reason:
          type: string
          description: Human-readable reason
        details:
          description: Additional details
        summary:
          type: string
          description: Optional short summary
      required:
        - error
    TeamNameExists:
      type: object
      properties:
        error:
          type: string
          enum:
            - TEAM_NAME_EXISTS
        existingTeamId:
          type: string
          description: Id of the team that already uses this name in the organization
      required:
        - error
        - existingTeamId
    TerraformTeamInvalidScopeFilter:
      type: object
      properties:
        error:
          type: string
          enum:
            - INVALID_SCOPE_FILTER
        reason:
          type: string
      required:
        - error
    TerraformTeamMultipleScopes:
      type: object
      properties:
        error:
          type: string
          enum:
            - TEAM_MULTIPLE_SCOPES
        reason:
          type: string
      required:
        - error
    TerraformTeamOrgContextRequired:
      type: object
      properties:
        error:
          type: string
          enum:
            - ORG_CONTEXT_REQUIRED
        reason:
          type: string
      required:
        - error
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT or Clerk ak_* API key
      description: >-
        Send `Authorization: Bearer <credential>` using either a Clerk session
        JWT or a Clerk API key (`ak_*`). API keys may identify a user (`user_*`)
        or organization (`org_*`) principal and are generated in the Clerk
        Dashboard under API keys.
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-token
      description: >-
        API token for authentication (or Admin API key). The token is scoped per
        organization and can be retrieved in the Organization Switcher.

````