---
title: "Document API"
space: "Framework"
url: "https://docs.frappe.io/framework/user/en/api/document"
updated: "2026-04-15"
---

A Document is an instance of a DocType. It is derived from the `frappe.model.Document` class and represents a single record in the database table.

## frappe.get_doc

`frappe.get_doc(doctype, name)`

Returns a Document object of the record identified by `doctype` and `name`. If no document is found, a `DoesNotExistError` is raised. If `doctype` is a Single DocType `name` is not required.

```
# get an existing document
doc = frappe.get_doc('Task', 'TASK00002')
doc.title = 'Test'
doc.save()

# get a single doctype
doc = frappe.get_doc('System Settings')
doc.timezone # Asia/Kolkata
```

`frappe.get_doc(dict)`

Returns a new Document object in memory which does not exist yet in the database.

```
# create a new document
doc = frappe.get_doc({
    'doctype': 'Task',
    'title': 'New Task'
})
doc.insert()
  

```

`frappe.get_doc(doctype={document_type}, key1 = value1, key2 = value2, ...)`

Returns a new Document object in memory which does not exist yet in the database.

```
# create new object with keyword arguments
user = frappe.get_doc(doctype='User', email_id='test@example.com')
user.insert()
```

## frappe.get_last_doc

`frappe.get_last_doc(doctype, filters, order_by)`

Returns the last Document object created under the mentioned `doctype`.

```
# get the last Task created
task = frappe.get_last_doc('Task')
```

You can also specify filters to refine your results. For instance, you can retrieve the last canceled Task by adding a filter.

```
# get the last available Cancelled Task
task = frappe.get_last_doc('Task', filters={"status": "Cancelled"})
```

By default, the `order_by` argument is set to `creation desc`, but this value can be overridden to use other non-standard fields that can serve the same purpose. For instance, you have a field `timestamp` under the **Task** DocType that tracks the time it was approved or marked valid instead of the time it was created.

```
# get the last Task created based on a non-standard field
task = frappe.get_last_doc('Task', filters={"Status": "Cancelled"}, order_by="timestamp desc")
```

Alternatively, you can choose to go completely against all of this and as a part of a joke change it to "creation asc" to retrieve the first document instead.

## frappe.get_cached_doc

Similar to `frappe.get_doc` but will look up the document in cache first before hitting the database.

## frappe.new_doc

`frappe.new_doc(doctype)`

Alternative way to create a new Document.

```
# create a new document
doc = frappe.new_doc('Task')
doc.title = 'New Task 2'
doc.insert()
```

## frappe.delete_doc

`frappe.delete_doc(doctype, name)`

Deletes the record and its children from the database. Also deletes other documents like Communication, Comments, etc linked to it.

```
frappe.delete_doc('Task', 'TASK00002')
```

## frappe.rename_doc

`frappe.rename_doc(doctype, old_name, new_name, merge=False)`

Rename a document's `name` (primary key) from `old_name` to `new_name`. If `merge` is `True` and a record with `new_name` exists, will merge the record with it.

```
frappe.rename_doc('Task', 'TASK00002', 'TASK00003')
  

```

> Rename will only work if **Allow Rename** is set in the DocType Form.

## frappe.get_meta

`frappe.get_meta(doctype)`

Returns meta information of `doctype`. This will also apply custom fields and property setters.

```
meta = frappe.get_meta('Task')
meta.has_field('status') # True
meta.get_custom_fields() # [field1, field2, ..]
  

```

To get the original document of DocType (without custom fields and property setters) use `frappe.get_doc('DocType', doctype_name)` 

## frappe.only_for

`frappe.only_for(roles, message=False)` 

Raises `frappe.PermissionError` if the current user does not have any of the permitted roles.

If the current user is `Administrator`, the permission check is skipped.

```
# restrict action to System Manager role
frappe.only_for("System Manager")


```

You can also allow multiple roles:

```
# allow multiple roles
frappe.only_for(["System Manager", "Accounts Manager"])


```

## frappe.get_docs

`frappe.get_docs(doctype, filters, *, chunk_size=1000, limit=None, limit_start=0, order_by="creation asc", as_iterator=False)` 

Returns a list of Document objects. Use `as_iterator=True` to fetch records in chunks for better memory management.

```
# Fetch specific documents with child tables
tasks = frappe.get_docs('Task', filters={'status': 'Open'}, limit=10)

for task in tasks:
    task.status = "Closed"
    task.save()

# Efficiently iterate through large datasets
leads = frappe.get_docs('Lead', as_iterator=True, chunk_size=500)

for lead in leads:
    lead.process_lead() # Custom controller method
```

## Document Methods

This section lists out common methods that are available on the `doc` object.

## doc.insert

This method inserts a new document into the database table. It will check for user permissions and execute `before_insert`, `validate`, `on_update`, `after_insert` methods if they are written in the controller.

It has some escape hatches that can be used to skip certain checks explained below.

```
doc.insert(
    ignore_permissions=True, # ignore write permissions during insert
    ignore_links=True, # ignore Link validation in the document
    ignore_if_duplicate=True, # dont insert if DuplicateEntryError is thrown
    ignore_mandatory=True # insert even if mandatory fields are not set
)
  

```

## doc.save

This method saves changes to an existing document. This will check for user permissions and execute `validate` before updating and `on_update` after updating values.

```
doc.save(
    ignore_permissions=True, # ignore write permissions during insert
    ignore_version=True # do not create a version record
)
  

```

## doc.delete

Delete the document record from the database table. This method is an alias to `frappe.delete_doc`.

```
doc.delete()
  

```

## doc.get_doc_before_save

Will return a version of the doc before the changes were made. You can use it to compare what changed from the last version.

```
old_doc = doc.get_doc_before_save()
if old_doc.price != doc.price:
    # price changed
    pass
```

## doc.has_value_changed

Will return True if the value of the given field was changed before and after saving.

```
price_changed = doc.has_value_changed("price")

if price_changed:
    pass
```

## doc.reload

Will get the latest values from the database and update the doc state.

When you are working with a document, it may happen that some other part of code updates the value of some field directly in the database. In such cases you can use this method to reload the doc.

```
doc.reload()
  

```

## doc.check_permission

Throw if the current user has no permission for the provided permtype.

```
doc.check_permission(permtype='write') # throws if no write permission
```

## doc.get_title

Get the document title based on `title_field` or field named **title** or **name**.

```
title = doc.get_title()
  

```

## doc.notify_update

Publish realtime event to indicate that the document has been modified. Client side event handlers react to this event by updating the form.

```
doc.notify_update()
```

## doc.db_set

Set a field value of the document directly in the database and update the modified timestamp.

> This method does not trigger controller validations and should be used very carefully.

```
# updates value in database, updates the modified timestamp
doc.db_set('price', 2300)

# updates value in database, will trigger doc.notify_update()
doc.db_set('price', 2300, notify=True)

# updates value in database, will also run frappe.db.commit()
doc.db_set('price', 2300, commit=True)

# updates value in database, does not update the modified timestamp
doc.db_set('price', 2300, update_modified=False)
  

```

## doc.append

Append a new item to a child table.

```
doc.append("childtable", {
    "child_table_field": "value",
    "child_table_int_field": 0,
    ...
})
  

```

## doc.get_url

Returns Desk URL for this document. For e.g: `/app/task/TASK00002`

```
url = doc.get_url()
  

```

## doc.add_comment

Add a comment to this document. Will show up in timeline in Form view.

```
# add a simple comment
doc.add_comment('Comment', text='Test Comment')

# add a comment of type Edit
doc.add_comment('Edit', 'Values changed')

# add a comment of type Shared
doc.add_comment("Shared", "{0} shared this document with everyone".format(user))
  

```

## doc.add_seen

Add the given/current user to list of users who have seen this document. Will update the `_seen` column in the table. It is stored as a JSON Array.

```
# add john to list of seen
doc.add_seen('john@doe.com')

# add session user to list of seen
doc.add_seen()
  

```

> This works only if **Track Seen** is enabled in the DocType.

## doc.add_viewed

Add a view log when a user views a document i.e opens the Form.

```
# add a view log by john
doc.add_viewed('john@doe.com')

# add a view log by session user
doc.add_viewed()
  

```

> This works only if **Track Views** is enabled in the DocType.

## doc.add_tag

Add a tag to a document. Tags are generally used to filter and group documents.

```
# add tags
doc.add_tag('developer')
doc.add_tag('frontend')
  

```

## doc.get_tags

Returns a list of tags associated with the specific document.

```
# get all tags
doc.get_tags()
  

```

## doc.run_method

Run method if defined in controller, will also trigger hooks if defined.

```
doc.run_method('validate')
  

```

## doc.queue_action

Run a controller method in background. If the method has an inner function, like `_submit` for `submit`, it will call that method instead.

```
doc.queue_action('send_emails', emails=email_list, message='Howdy')
  

```

## doc.get_children()

> Only available on tree DocTypes (inherited from `NestedSet`).

Returns a generator that yields an instance of `NestedSet` for each child record.

```
for child_doc in doc.get_children():
    print(child_doc.name)
  

```

It can also be applied recursively:

```
for child_doc in doc.get_children():
    print(child_doc.name)
    for grandchild_doc in child_doc.get_children():
        print(grandchild_doc.name)
  

```

## doc.get_parent()

> Only available on tree DocTypes (inherited from `NestedSet`).

Returns an instance of `NestedSet` for the parent record.

```
parent_doc = doc.get_parent()
grandparent_doc = parent_doc.get_parent()
```

## doc.db_insert()

Serialize and insert a document into database. Warning: This bypasses all validations and controller methods that might be required to run before and after inserting. When in doubt use `doc.insert()` instead.

```
doc = frappe.get_doc(doctype="Controller", data="")
doc.db_insert()
```

## doc.db_update()

Serialize and update a document into database. Warning: This bypasses all validations and controller methods that might be required to run before and after updating. When in doubt use `doc.save()` instead.

```
doc = frappe.get_last_doc("User")
doc.last_active = now()
doc.db_update()
  

```

