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

# Update a project

> Update a project entity. Include only the fields you want to change.

**Time estimation** — You can switch estimation mode by updating `estimated_by_position` / `estimation_by_categories` together with `users_positions` / `categories`. Positions present in the project but absent from the `users_positions` array will have their estimated hours reset to 0 (or be soft-deleted if no hours have been logged against them).

> These fields are unrelated to **Project Estimates** (`/projects/{project_id}/project_estimate`), which manage budget line items.



## OpenAPI

````yaml /api-reference/openapi.json put /projects/{project_id}
openapi: 3.1.0
info:
  title: COR API
  description: >-
    The COR API lets you integrate with projectcor.com applications using simple
    HTTP methods, in either XML or JSON formats, making this an ideal API for
    developing integrations with other softwares, external clients or mobile
    applications
  version: 1.0.0
servers:
  - url: https://api.projectcor.com/v1
    description: Production server
security:
  - bearerAuth: []
paths:
  /projects/{project_id}:
    put:
      tags:
        - Projects
      summary: Update a project
      description: >-
        Update a project entity. Include only the fields you want to change.


        **Time estimation** — You can switch estimation mode by updating
        `estimated_by_position` / `estimation_by_categories` together with
        `users_positions` / `categories`. Positions present in the project but
        absent from the `users_positions` array will have their estimated hours
        reset to 0 (or be soft-deleted if no hours have been logged against
        them).


        > These fields are unrelated to **Project Estimates**
        (`/projects/{project_id}/project_estimate`), which manage budget line
        items.
      parameters:
        - name: project_id
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProjectPutUpdateBody'
            examples:
              updateLabels:
                summary: Update labels only
                value:
                  labels: []
              switchToByPositions:
                summary: Switch to estimation by positions
                value:
                  estimated_by_position: true
                  estimation_by_categories: false
                  users_positions:
                    - id: 1
                      estimated_time: 80
                    - id: 2
                      estimated_time: 40
              updateHourlyRates:
                summary: Enable hourly rates with ratecard
                value:
                  estimated_by_hourly_rates: true
                  ratecard_id: 3
                  income_type: hourly_rate
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ProjectPutUpdateBody'
      responses:
        '200':
          description: Project updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
components:
  schemas:
    ProjectPutUpdateBody:
      type: object
      description: >-
        Fields to update on a project. Include only the properties you want to
        change.
      properties:
        name:
          type: string
          description: Project Name
        client_id:
          type: integer
          description: Client ID
        brief:
          type: string
          description: Project description or brief
        start:
          type: string
          format: date
          description: Project start date (YYYY-MM-DD)
        end:
          type: string
          format: date
          description: Project end date (YYYY-MM-DD)
        pm_id:
          type: integer
          description: Project Manager User ID
        estimated_time:
          type: number
          description: Estimated hours for the project
        billable:
          type: boolean
          description: Whether the project is billable
        status:
          type: string
          description: Project status
        currency_id:
          type: integer
          description: Currency ID
        evaluation_date:
          type: string
          format: date
          description: Project evaluation date (YYYY-MM-DD)
        estimated:
          type: number
          description: Estimated monetary value for the project
        fee_id:
          type: integer
          description: Fee ID
        contract_id:
          type: integer
          description: Contract ID
        deliverables:
          type: string
          description: Project deliverables description
        work_order:
          type: string
          description: Work order number or code
        income_type:
          type: string
          enum:
            - fee
            - one_time
            - hourly_rate
            - contract
          description: Income type for the project
        archived:
          type: boolean
          description: Whether the project is archived
          default: false
        labels:
          type: array
          maxItems: 50
          description: >-
            Label IDs to assign to the project. Omit this field entirely to
            leave existing labels unchanged. Send an empty array (`[]`) to
            remove all labels from the project. Each entry may be an integer ID
            or an object with an `id` property (for example `[101, 102]`).
            Maximum 50 labels. Use **Get Categories and Labels** with
            `model=project` (`GET /categories/labels-model?model=project`) to
            list project label objects for your company; use each label's `id`
            in this array.
          items:
            oneOf:
              - type: integer
              - type: object
                required:
                  - id
                properties:
                  id:
                    type: integer
        estimated_by_position:
          type: boolean
          description: >-
            When `true`, time estimation is split per position via the
            `users_positions` array. Mutually exclusive with
            `estimation_by_categories`.
        estimation_by_categories:
          type:
            - boolean
            - integer
          description: >-
            When truthy (`true` or `1`), time estimation is split per category
            via the `categories` array. Mutually exclusive with
            `estimated_by_position`.
        estimated_by_hourly_rates:
          type: boolean
          description: >-
            When `true`, the project income is calculated from hourly rates
            using the assigned ratecard.
        ratecard_id:
          type: integer
          description: >-
            Ratecard ID. Alias for `user_positions_header_id` — if both are
            sent, `ratecard_id` takes precedence.
        users_positions:
          type: array
          description: >-
            Positions involved in the project with optional per-position hour
            estimates. Positions present in the project but absent from this
            array will have their estimated hours set to 0 (or be soft-deleted
            if no hours have been logged).
          items:
            $ref: '#/components/schemas/ProjectUserPositionInput'
        categories:
          type: array
          description: >-
            Categories assigned to the project with optional per-category hour
            estimates.
          items:
            $ref: '#/components/schemas/ProjectCategoryInput'
        exchange:
          type: number
          description: >-
            Exchange rate when project currency differs from the company base
            currency.
        currency_change_amount:
          type: number
          description: >-
            Original estimated amount in the selected currency before exchange
            conversion.
    Project:
      type: object
      properties:
        id:
          type: integer
          description: Unique project identifier
        name:
          type: string
          description: Project name
        brief:
          type: string
          description: Project brief/description
        client_id:
          type: integer
          description: Associated client ID
        health:
          type: integer
          enum:
            - 1
            - 2
            - 3
            - 4
          description: >-
            Project health indicator: 1 (on track), 2 (at risk), 3 (delayed), 4
            (critical)
        status:
          type: string
          enum:
            - active
            - finished
            - suspended
          description: Project status
        start:
          type: string
          format: date-time
          description: Project start date
        end:
          type: string
          format: date-time
          description: Project end date
        estimated_time:
          type: number
          description: Estimated hours for the project
        elapsed_time:
          type: number
          description: Hours already logged
        profitability_now:
          type: number
          description: Current profitability percentage
        estimated_profitability:
          type: number
          description: Estimated profitability percentage
        archived:
          type: boolean
          description: Whether the project is archived
        billable:
          type: boolean
          description: Whether the project is billable
        income_type:
          type: string
          enum:
            - fee
            - one_time
            - hourly_rate
            - contract
          description: Project billing type
        pm_id:
          type: integer
          description: Project Manager user ID
        created_by:
          type: integer
          description: User ID who created the project
        company_id:
          type: integer
          description: Company ID
        template_id:
          type: integer
          description: Project template ID used
        brand_id:
          type: integer
          description: Associated brand ID
        product_id:
          type: integer
          description: Associated product ID
        total_estimated:
          type: number
          description: Total estimated budget
        created_at:
          type: string
          format: date-time
          description: Creation timestamp
        updated_at:
          type: string
          format: date-time
          description: Last update timestamp
        labels:
          type: array
          description: >-
            IDs of labels assigned to this project. Resolve names and styling
            via **Get Categories and Labels** with `model=project` (`GET
            /categories/labels-model?model=project`), which returns label
            objects including the same `id` values.
          items:
            type: integer
        client:
          type: object
          description: Associated client object
          properties:
            id:
              type: integer
            name:
              type: string
            client_status_id:
              type: integer
        pm:
          type: object
          description: Project Manager details
          properties:
            id:
              type: integer
            first_name:
              type: string
            last_name:
              type: string
            email:
              type: string
            role_id:
              type: integer
        estimated_by_position:
          type: boolean
          description: Whether time estimation is split per position
        estimation_by_categories:
          type:
            - boolean
            - integer
          description: Whether time estimation is split per category
        estimated_by_hourly_rates:
          type:
            - boolean
            - string
          description: Whether income is calculated from hourly rates using a ratecard
        user_positions_header_id:
          type: integer
          nullable: true
          description: ID of the ratecard assigned to this project
        fee_id:
          type: integer
          nullable: true
          description: Associated fee ID
        contract_id:
          type: integer
          nullable: true
          description: Associated contract ID
        usersPositionsProject:
          type: array
          description: >-
            Positions assigned to the project with their estimated and logged
            hours. Only present when fetching a single project (`GET
            /projects/{project_id}`).
          items:
            type: object
            properties:
              id:
                type: integer
                description: Row ID in user_positions_projects
              user_positions_unified_id:
                type: integer
                description: Unified position ID
              project_id:
                type: integer
              estimated_hours:
                type: number
                description: Estimated hours for this position
              hours_charged:
                type: number
                description: Hours already logged against this position
              total_cost:
                type: number
                description: Total cost accrued for this position
              userPositionName:
                type: object
                nullable: true
                description: Position name in the requested language
                properties:
                  name:
                    type: string
        categoriesProject:
          type: array
          description: >-
            Categories assigned to the project with their estimated and logged
            hours. Only present when fetching a single project.
          items:
            type: object
            properties:
              id:
                type: integer
              category_id:
                type: integer
              estimated_hours:
                type: number
              hours_charged:
                type: number
              total_cost:
                type: number
        ratecard:
          type: object
          nullable: true
          description: >-
            Ratecard assigned to this project. Only present when fetching a
            single project.
          properties:
            id:
              type: integer
            name:
              type: string
            original_name:
              type: string
            percent:
              type: number
            currency_id:
              type: integer
              nullable: true
            linked_to_base_price:
              type: boolean
    ProjectUserPositionInput:
      type: object
      required:
        - id
      properties:
        id:
          type: integer
          description: >-
            Unified position ID (`user_positions_unified.id`). Use **Get
            Position Segment Labels** or the User Positions endpoints to list
            available positions.
        estimated_time:
          type: number
          description: >-
            Estimated hours for this position. Required when
            `estimated_by_position` is `true`. The server persists this value as
            `estimated_hours` in the `user_positions_projects` table.
    ProjectCategoryInput:
      type: object
      required:
        - id
      properties:
        id:
          type: integer
          description: Category ID.
        estimated_time:
          type: number
          description: >-
            Estimated hours for this category. Required when
            `estimation_by_categories` is truthy.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````