project.project: fields, relations and API
The project.project model ("Project") is a persistent model declared by the Project module, then extended by 13 other modules. It exposes 129 fields, 84 of them declared directly on the model; 26 fields from other models point to it. Below you will find every field with its technical name, type, label and relations, followed by an Odoo 19 JSON-2 API call.
Model identity
- Technical name
project.project- Label
- Project
- Type
- Persistent (models.Model)
- SQL table
project_project- Origin module
- Project (
project) - Extended by
- hr_timesheet, project_account, project_hr_expense, project_mrp, project_mrp_account, sale_project, project_purchase, project_stock, project_sale_expense, project_sms, project_stock_account, sale_project_stock, sale_timesheet
- Default order (_order)
sequence, name, id
Model fields
84 own fields, 39 inherited from mixins and 6 automatic ORM fields. Click a name to get a direct link to that field.
129 of 129 fields shown
| Technical name | Label | Type | Details |
|---|---|---|---|
| access_instruction_message | Access Instruction Message | char | computed |
| account_id | Account | many2one | |
| active | Active | boolean | |
| alias_id | Alias Internal email associated with this project. Incoming emails are automatically synchronized with Tasks (or optionally Issues if the Issue Tracker module is installed). | many2one | |
| allocated_hours | Allocated Time | float | added by Task Logs ( |
| allow_billable | Billable | boolean | added by Sales - Project ( |
| allow_milestones | Milestones | boolean | |
| allow_recurring_tasks | Recurring Tasks | boolean | |
| allow_task_dependencies | Task Dependencies | boolean | |
| allow_timesheets | Timesheets | boolean | computed, stored added by Task Logs ( |
| analytic_account_active | Active Account | boolean | related: added by Task Logs ( |
| analytic_account_balance | Analytic Account Balance | monetary | related: |
| billing_type | Billing Type | selection | requiredcomputed, stored Values: added by Sales Timesheet ( |
| bom_count | Bom Count | integer | computed added by MRP Project ( |
| can_mark_milestone_as_done | Can Mark Milestone As Done | boolean | computed |
| closed_task_count | Closed Task Count | integer | computed |
| collaborator_count | # Collaborators | integer | computed |
| collaborator_ids | Collaborators | one2many | inverse: |
| color | Color Index | integer | |
| company_id | Company | many2one | computed, stored |
| currency_id | Currency | many2one | read-onlycomputed |
| date | Expiration Date Date on which this project ends. The timeframe defined on the project is taken into account when viewing its planning. | date | |
| date_start | Start Date | date | |
| description | Description Description to provide more information and context about this project | html | |
| display_sales_stat_buttons | Display Sales Stat Buttons | boolean | computed added by Sales - Project ( |
| duration_tracking | Duration Tracking | json | |
| effective_hours | Time Spent | float | computed added by Task Logs ( |
| encode_uom_in_days | Encode Uom In Days | boolean | computed added by Task Logs ( |
| favorite_user_ids | Members | many2many | |
| has_any_so_to_invoice | Has SO to Invoice | boolean | computed added by Sales - Project ( |
| has_any_so_with_nothing_to_invoice | Has a SO with an invoice status of No | boolean | computed added by Sales - Project ( |
| invoice_count | Invoice Count | integer | computed added by Sales - Project ( |
| is_favorite | Show Project on Dashboard | boolean | computed |
| is_internal_project | Is Internal Project | boolean | computed added by Task Logs ( |
| is_milestone_deadline_exceeded | Is Milestone Deadline Exceeded | boolean | computed |
| is_milestone_exceeded | Is Milestone Exceeded | boolean | computed |
| is_project_overtime | Project in Overtime | boolean | computed added by Task Logs ( |
| is_template | Is Template | boolean | |
| label_tasks | Use Tasks as Name used to refer to the tasks of your project e.g. tasks, tickets, sprints, etc... | char | translatable |
| last_update_color | Last Update Color | integer | computed |
| last_update_id | Last Update | many2one | |
| last_update_status | Last Update Status | selection | requiredcomputed, stored Values: |
| milestone_count | Milestone Count | integer | computed |
| milestone_count_reached | Milestone Count Reached | integer | computed |
| milestone_ids | Milestone | one2many | inverse: |
| milestone_progress | Milestones Reached | integer | computed |
| name | Name | char | requiredtranslatable |
| next_milestone_id | Next Milestone | many2one | computed |
| open_task_count | Open Task Count | integer | computed |
| partner_id | Customer | many2one | computed, stored |
| pricing_type | Pricing The task rate is perfect if you would like to bill different services to different customers at different rates. The fixed rate is perfect if you bill a service at a fixed rate per hour or day worked regardless of the employee who performed it. The employee rate is preferable if your employees deliver the same service at a different rate. For instance, junior and senior consultants would deliver the same service (= consultancy), but at a different rate because of their level of seniority. | selection | computed Values: added by Sales Timesheet ( |
| privacy_visibility | Visibility Project and Task Visibility: - Invited internal users: Can access only the project or tasks they follow. Assignees automatically get access. - Invited internal and portal users: Same as above, extended to portal users. - All internal users: Full access to the project and all its tasks. - All internal and invited portal users: Internal users get full access. Portal users can access only the project or tasks they follow. Portal Access Levels: - Read-only: Portal users see tasks via their portal but can’t edit them. - Edit (limited): Portal users access kanban/list views and can edit limited fields on followed tasks. - Edit: Same as above, with access to all tasks. Other Rules: - Internal users can open a task from a direct link, even without project access. - Project admins have access to private projects, even if not followers. | selection | required Values: |
| privacy_visibility_warning | Privacy Visibility Warning | char | computed |
| production_count | Production Count | integer | computed added by MRP Project ( |
| purchase_orders_count | # Purchase Orders | integer | computed added by Project Purchase ( |
| reinvoiced_sale_order_id | Sales Order Products added to stock pickings, whose operation type is configured to generate analytic costs, will be re-invoiced in this sales order if they are set up for it. | many2one | added by Sales - Project ( |
| remaining_hours | Time Remaining | float | computed added by Task Logs ( |
| resource_calendar_id | Working Time | many2one | computed |
| sale_line_employee_ids | Sale line/Employee map Sales order item that will be selected by default on the timesheets of the corresponding employee. It bypasses the sales order item defined on the project and the task, and can be modified on each timesheet entry if necessary. In other words, it defines the rate at which an employee's time is billed based on their expertise, skills or experience, for instance. If you would like to bill the same service at a different rate, you need to create two separate sales order items as each sales order item can only have a single unit price at a time. You can also define the hourly company cost of your employees for their timesheets on this project specifically. It will bypass the timesheet cost set on the employee. | one2many | inverse: added by Sales Timesheet ( |
| sale_line_id | Sales Order Item Sales order item that will be selected by default on the tasks and timesheets of this project, except if the employee set on the timesheets is explicitely linked to another sales order item on the project. It can be modified on each task and timesheet entry individually if necessary. | many2one | computed, stored added by Sales - Project ( |
| sale_order_count | Sale Order Count | integer | computed added by Sales - Project ( |
| sale_order_id | Sale Order | many2one | related: added by Sales - Project ( |
| sale_order_line_count | Sale Order Line Count | integer | computed added by Sales - Project ( |
| sale_order_state | Sale Order State | selection | related: added by Sales - Project ( |
| sequence | Sequence | integer | |
| show_ratings | Show Ratings | boolean | computed |
| stage_id | Stage | many2one | |
| stage_id_color | Stage Color | integer | related: |
| tag_ids | Tags | many2many | |
| task_completion_percentage | Task Completion Percentage | float | computed |
| task_count | Task Count | integer | computed |
| task_ids | Tasks | one2many | inverse: |
| task_properties_definition | Task Properties | properties_definition | |
| tasks | Task Activities | one2many | inverse: |
| timesheet_encode_uom_id | Timesheet Encode Uom | many2one→ uom.uom | computed added by Task Logs ( |
| timesheet_ids | Associated Timesheets | one2many | inverse: added by Task Logs ( |
| timesheet_product_id | Timesheet Product Service that will be used by default when invoicing the time spent on a task. It can be modified on each task individually by selecting a specific sales order item. | many2one | computed, stored added by Sales Timesheet ( |
| total_timesheet_time | Total amount of time (in the proper unit) recorded in the project, rounded to the unit. | float | computed added by Task Logs ( |
| type_ids | Tasks Stages | many2many | |
| update_count | Update Count | integer | computed |
| update_ids | Update | one2many | inverse: |
| user_id | Project Manager | many2one | |
| vendor_bill_count | Vendor Bill Count | integer | related: added by Sales - Project ( |
| warning_employee_rate | Warning Employee Rate | boolean | computed added by Sales Timesheet ( |
| access_token | Security Token | char | inherited from portal.mixin |
| access_url | Portal Access URL Customer Portal URL | char | computed inherited from portal.mixin |
| access_warning | Access warning | text | computed inherited from portal.mixin |
| activity_calendar_event_id | Next Activity Calendar Event | many2one | computed inherited from mail.activity.mixin |
| activity_date_deadline | Next Activity Deadline | date | read-onlycomputed inherited from mail.activity.mixin |
| activity_exception_decoration | Activity Exception Decoration Type of the exception activity on record. | selection | computed Values: inherited from mail.activity.mixin |
| activity_exception_icon | Icon Icon to indicate an exception activity. | char | computed inherited from mail.activity.mixin |
| activity_ids | Activities | one2many | inverse: inherited from mail.activity.mixin |
| activity_state | Activity State Status based on activities Overdue: Due date is already passed Today: Activity date is today Planned: Future activities. | selection | computed Values: inherited from mail.activity.mixin |
| activity_summary | Next Activity Summary | char | related: inherited from mail.activity.mixin |
| activity_type_icon | Activity Type Icon | char | related: inherited from mail.activity.mixin |
| activity_type_id | Next Activity Type | many2one | related: inherited from mail.activity.mixin |
| activity_user_id | Responsible User | many2one | read-onlycomputed inherited from mail.activity.mixin |
| alias_defaults | Alias Defaults | text | inherited from mail.alias.mixin |
| alias_domain | Alias Domain Name | char | related: inherited from mail.alias.mixin.optional |
| alias_domain_id | Alias Domain | many2one | related: inherited from mail.alias.mixin.optional |
| alias_email | Email Alias | char | computed inherited from mail.alias.mixin.optional |
| alias_name | Alias Name | char | inherited from mail.alias.mixin |
| auto_account_id | Analytic Account | many2one | computed inherited from analytic.plan.fields.mixin |
| has_message | Has Message | boolean | computed inherited from mail.thread |
| is_rotting | Rotting | boolean | computed inherited from mail.tracking.duration.mixin |
| message_attachment_count | Attachment Count | integer | computed inherited from mail.thread |
| message_follower_ids | Followers | one2many | inverse: inherited from mail.thread |
| message_has_error | Message Delivery error If checked, some messages have a delivery error. | boolean | computed inherited from mail.thread |
| message_has_error_counter | Number of errors Number of messages with delivery error | integer | computed inherited from mail.thread |
| message_has_sms_error | SMS Delivery error If checked, some messages have a delivery error. | boolean | computed inherited from mail.thread |
| message_ids | Messages | one2many | inverse: inherited from mail.thread |
| message_is_follower | Is Follower | boolean | computed inherited from mail.thread |
| message_needaction | Action Needed If checked, new messages require your attention. | boolean | computed inherited from mail.thread |
| message_needaction_counter | Number of Actions Number of messages requiring action | integer | computed inherited from mail.thread |
| message_partner_ids | Followers (Partners) | many2many | computed inherited from mail.thread |
| my_activity_date_deadline | My Activity Deadline | date | read-onlycomputed inherited from mail.activity.mixin |
| rating_avg | Average Rating | float | computed inherited from rating.parent.mixin |
| rating_avg_percentage | Average Rating (%) | float | computed inherited from rating.parent.mixin |
| rating_count | # Ratings | integer | computed inherited from rating.parent.mixin |
| rating_ids | Ratings | one2many | inverse: inherited from rating.parent.mixin |
| rating_percentage_satisfaction | Rating Satisfaction Percentage of happy ratings | integer | computed inherited from rating.parent.mixin |
| rotting_days | Days Rotting Day count since this resource was last updated | integer | computed inherited from mail.tracking.duration.mixin |
| website_message_ids | Website Messages Website communication history | one2many | inverse: inherited from mail.thread |
| create_date | Created on | datetime | read-onlyautomatic |
| create_uid | Created by | many2one | read-onlyautomatic |
| display_name | Display Name | char | read-onlycomputedautomatic |
| id | ID | integer | read-onlyautomatic |
| write_date | Last Updated on | datetime | read-onlyautomatic |
| write_uid | Last Updated by | many2one | read-onlyautomatic |
Relations
Models linked from this model
- account.analytic.account: account_id
- account.analytic.line: timesheet_ids
- mail.alias: alias_id
- product.product: timesheet_product_id
- project.collaborator: collaborator_ids
- project.milestone: milestone_ids, next_milestone_id
- project.project.stage: stage_id
- project.sale.line.employee.map: sale_line_employee_ids
- project.tags: tag_ids
- project.task: task_ids, tasks
- project.task.type: type_ids
- project.update: last_update_id, update_ids
- res.company: company_id
- res.currency: currency_id
- res.partner: partner_id
- res.users: favorite_user_ids, user_id
- resource.calendar: resource_calendar_id
- sale.order: reinvoiced_sale_order_id, sale_order_id
- sale.order.line: sale_line_id
- uom.uom: timesheet_encode_uom_id
Fields of other models pointing here
- account.analytic.line: project_id
- mrp.bom: project_id
- mrp.production: project_id
- product.template: project_id, project_template_id
- project.collaborator: project_id
- project.milestone: project_id
- project.sale.line.employee.map: project_id
- project.tags: project_ids
- project.task: project_id
- project.task.burndown.chart.report: project_id
- project.task.type: project_ids
- project.task.type.delete.wizard: project_ids
- project.template.create.wizard: template_id
- project.update: project_id
- purchase.order: project_id
- report.project.task.user: project_id
- res.company: internal_project_id
- res.config.settings: internal_project_id
- res.users: favorite_project_ids
- sale.order: project_id, project_ids
- sale.order.line: project_id
- sale.report: project_id
- stock.picking: project_id
- timesheets.analysis.report: project_id
Reading this model through the API
Odoo 19 JSON-2 API call reading the first five records with real fields of the model. Replace the instance, database and API key with your own.
curl -X POST "https://your-instance.odoo.com/json/2/project.project/search_read" \
-H "Authorization: bearer $ODOO_API_KEY" \
-H "X-Odoo-Database: your-db" \
-H "Content-Type: application/json" \
-d '{"domain":[],"fields":["name","billing_type","last_update_status","privacy_visibility","account_id"],"limit":5}'import requests
BASE_URL = "https://your-instance.odoo.com/json/2"
headers = {"Authorization": f"bearer {API_KEY}", "X-Odoo-Database": "your-db"}
res = requests.post(
f"{BASE_URL}/project.project/search_read",
headers=headers,
json={"domain": [], "fields": ["name","billing_type","last_update_status","privacy_visibility","account_id"], "limit": 5},
)
res.raise_for_status()
print(res.json())- External API access requires Odoo's Custom plan.
- XML-RPC and JSON-RPC will be removed in Odoo 22 (fall 2028): use JSON-2.
- The access rights and record rules of the key's user apply.
Cite this tool
Writing a tutorial, internal documentation or a forum answer? Copy this link to send your readers to the up-to-date reference.
<a href="https://aidoo.ai/en/outils/explorateur-modeles-odoo/project-project">project.project (Odoo 19.0)</a>Sources
Data verified on September 23, 2026 · Odoo 19.0 Community
Have an Odoo project, or want to put your ERP to work with AI? Let's talk
Implementation, custom module development, connecting Claude or ChatGPT to your data: tell us about your context and we will reply within 24 business hours.