Database views let users see the same data in different ways — for example, as a table, board, calendar, timeline, gallery, list, form, chart, map, or dashboard. Each view can have its own filters, sorts, and layout configuration, so a single database can serve many different workflows.The Notion API exposes views as first-class resources. This means integrations can programmatically manage the same view presets that users create in the UI, enabling use cases like workspace bootstrapping, migration tooling, and automated view setup.In this guide, you’ll learn:
How views relate to databases and data sources.
What happens by default when you create a database.
A view is scoped to a single data source within a database. It defines how pages in that data source are filtered, sorted, and displayed.The view object looks like this:
type — The layout type. One of: table, board, list, calendar, timeline, gallery, form, chart, map, or dashboard.
data_source_id — Which data source this view is “over”. A database can have multiple data sources, and each view targets exactly one. For dashboard views this is null since dashboards contain multiple widget views, each with their own data source.
filter and sorts — Use the same shapes as the filter and sort parameters in data source queries.
quick_filters — A map of property-level filters that appear in the view’s filter bar. Keys are property names or IDs, values are filter conditions (same shape as property filters, without the property field). See Quick filters.
configuration — Type-specific presentation settings that vary by view type. This is a discriminated union keyed on type — see View configuration for the full schema per view type. This field is null when no custom configuration has been set.
parent — Always a database. Views are retrieved and managed through their parent database.
dashboard_view_id — Only present on widget views that belong to a dashboard. References the parent dashboard view’s ID.
The list endpoint returns minimal view references (just object and id). To get full view details including filters, sorts, and configuration, retrieve each view individually.
Create a new view by specifying the target data source, a name, and a view type. You must also provide one of database_id (to create a top-level view on a database), view_id (to add a widget view to an existing dashboard), or create_database (to create a linked database view on a page). You can optionally include filters, sorts, and a configuration object. For the full parameter reference, see Create a view.
database_id and data_source_id are different IDs. The database_id is the database container’s ID (the same ID returned by the Retrieve a database endpoint). The data_source_id is the ID of a specific data source within that database (found in the database’s data_sources array). Most databases have a single data source, but both IDs are required.
The response is the newly created view object with all fields populated.
Views in a database can be configured to show pages from a data source that’s owned by another database. In Notion, this is called a linked database (or linked view), and it’s useful for showing the same underlying data in multiple places—for example, putting filtered views of your Tasks, Projects, and Bugs on a single dashboard page.In the API, the main requirement is that your integration has access to both the database that owns the data source, and the database you’re creating the view in.
Filtering by multiple select valuesTo filter a select property by multiple values (e.g. Priority is “Low” or “Medium”), use a compound or filter with separate equals conditions:
The API validates select and status filter values against the property’s configured options. For status properties, group names (e.g. “To-do”, “In progress”, “Complete”) are also accepted. If a value doesn’t match any existing option or group, the API returns a descriptive error listing the available values.
The ID of the database to create the view in. Mutually exclusive with view_id and create_database.
view_id
The ID of a dashboard view to add this view to as a widget. Mutually exclusive with database_id and create_database.
create_database
Creates a linked database view on a page referencing an existing data source. See Creating a linked database view. Mutually exclusive with database_id and view_id.
filter
A filter object to apply. Uses the same shape as data source queries.
sorts
An array of sort objects. Uses the same shape as data source queries.
quick_filters
A map of quick filters for the view’s filter bar. Keys are property names or IDs, values are filter conditions.
configuration
A view configuration object. The type field inside must match the view type.
position
Where to place the new view in the database’s view tab bar. Only applicable when database_id is provided. See View positioning. Defaults to appending at the end.
placement
Where to place the new widget in a dashboard layout. Only applicable when view_id is provided. See Widget placement. Defaults to creating a new row at the end.
You must provide exactly one of database_id, view_id, or create_database. Use database_id to create a top-level view on a database. Use view_id to add a widget view to an existing dashboard — see Dashboard views for details. Use create_database to create a linked database view on a page — see Creating a linked database view.
Finding the data source IDIf you already have a database ID, call the Retrieve a database endpoint. The response includes a data_sources array with each data source’s id and name.
When creating a top-level database view (using database_id), you can control where it appears in the view tab bar with the position parameter. This is a discriminated union on the type field:
Variant
Fields
Description
start
type
Places the new view as the first tab.
end
type
Places the new view as the last tab (default).
after_view
type, view_id
Places the new view immediately after the specified view.
Report incorrect code
Copy
Ask AI
{ "position": { "type": "start" }}
The position parameter is only valid when database_id is provided. It cannot be used with view_id (dashboard widget creation).
Use the create_database parameter to create a lightweight linked database view on a page that references an existing data source. This creates a new database container on the target page with a single view over the specified data source — similar to inserting a “linked view of database” in the Notion UI.This differs from POST /v1/databases, which creates a full standalone database with its own schema, data source, and default view. With create_database, the view points to an existing data source owned by another database, so no new schema is created.
The create_database object accepts the following fields:
Field
Required
Description
parent
Yes
The parent page for the linked database. Must be { "type": "page_id", "page_id": "..." }.
position
No
Controls where the new database block appears within the parent page. Use { "type": "after_block", "block_id": "..." } to place it after a specific block. The referenced block must be a direct child of the parent page. Defaults to appending at the end.
All view types are supported with create_database, including form views with full form configuration and dashboard views. Dashboard views are created with an empty layout — add widgets to them via separate POST /v1/views calls with view_id.
Your integration must have access to both the target page (where the new database container is created) and the database that owns the data source being referenced.
The response is a partial view object containing only identity fields (object, id, parent, and type). Full view details like filters, sorts, and configuration are not included since the view has been deleted.
Deleting a view cannot be undone through the API. The view will no longer appear in the database’s view list.
A database must always have at least one view. Attempting to delete the last remaining view returns a validation_error. To remove the database entirely, set in_trash to true via the update database endpoint instead.
The configuration field on a view object controls type-specific presentation settings — things like column widths, grouping, cover images, subtasks, and more. It is a discriminated union keyed on the type field, which must match the view’s top-level type.You can pass configuration when creating or updating a view. Nullable fields accept null to clear the setting.
Chart views display database data as visual charts. The configuration uses a flat object with chart_type as a required discriminator. Available fields vary by chart type.
When color_by_value is enabled on a bar or column chart, each bar is shaded along a gradient based on its numeric value — higher values appear in a darker shade and lower values in a lighter shade. This is useful for quickly spotting relative magnitude across categories. Combine with color_theme to control the gradient’s base color.Required fields:
Field
Type
Description
type
"chart"
Required. Must be "chart".
chart_type
"column" | "bar" | "line" | "donut" | "number"
Required. The chart type: "column" (vertical bars), "bar" (horizontal bars), "line", "donut", or "number" (single value display).
Data configuration fields:Charts support two data modes: grouped data (aggregate values by grouping on a property) and results (use raw property values directly).
Field
Type
Description
x_axis
object | null
X-axis grouping configuration for column/bar/line/donut charts using grouped data. Uses the same group-by configuration shape. Null when using results mode. Pass null to clear.
y_axis
object | null
Y-axis aggregation for column/bar/line/donut charts using grouped data. Null when using results mode. Pass null to clear.
x_axis_property_id
string | null
Property ID for x-axis name values when using results (raw property values) mode. Pass null to clear.
y_axis_property_id
string | null
Property ID for y-axis numeric values when using results mode. Pass null to clear.
value
object | null
Aggregation configuration for number charts (single value display). Pass null to clear.
stack_by
object | null
Stack-by grouping configuration for stacked/grouped charts (column/bar/line only). Uses the same group-by configuration shape. Pass null to clear.
Whether to hide groups with no data on the x-axis.
legend_position
"off" | "bottom" | "side"
Legend display position. "off" hides the legend.
show_data_labels
boolean
Whether to show data value labels on chart elements.
color_by_value
boolean
Whether to apply gradient coloring to chart elements based on their numeric value. Higher values appear in a darker shade and lower values in a lighter shade.
Required. The rows that make up the dashboard layout. Each row contains one or more widget modules.
Dashboard row object:
Field
Type
Description
id
string
The ID of this row module.
widgets
array
The widget modules within this row.
height
integer
Fixed height of the row in pixels.
Dashboard widget object:
Field
Type
Description
id
string
The ID of this widget module.
view_id
string
The ID of the collection view rendered by this widget.
width
integer
Width of the widget in a 12-column grid (1–12). 12 means full width.
row_index
integer
The 0-based index of the row this widget belongs to. Widgets in the same row share the same row_index.
Dashboard configuration is read-only — it is returned when retrieving a dashboard view but cannot be set directly when creating or updating a view. The layout structure is managed by creating and deleting widget views via the view_id parameter on the create endpoint.
The properties array controls which database properties are visible in the view and how they are displayed. Each entry targets a single property by its ID or name.
Required. The property ID or property name. When a name is provided, the API resolves it to the corresponding property ID. If the string matches both a property ID and a different property’s name, the ID match takes priority.
visible
boolean
Whether the property is visible in this view.
width
integer (>= 0)
Column width in pixels (table views only).
wrap
boolean
Whether to wrap content in this property cell or card.
status_show_as
"select" | "checkbox"
How to display status properties.
card_property_width_mode
"full_line" | "inline"
Property width mode in compact card layouts (board/gallery).
date_format
enum
Display format for date properties. One of: "full", "short", "month_day_year", "day_month_year", "year_month_day", "relative".
time_format
enum
Time display format for date properties. One of: "12_hour", "24_hour", "hidden".
Group-by lets you organize rows or cards into sections based on a property’s values. The shape varies by property type, forming a discriminated union on the type field.All group-by variants share these fields:
Field
Type
Description
type
string
Required. The property type being grouped. Determines which additional fields are available.
property_id
string
Required. The property ID to group by.
sort
object
Required. Sort order for the groups. An object with type: "manual", "ascending", or "descending".
hide_empty_groups
boolean
Whether to hide groups with no items.
The following table shows which type values are supported and what extra fields each variant accepts:
type value(s)
Extra required fields
Extra optional fields
select, multi_select
—
—
status
group_by: "group" (by status group: To Do/In Progress/Done) or "option" (by individual option)
group_by: "exact" or "alphabet_prefix" (first letter)
—
number
—
range_start, range_end, range_size (>= 1) for bucket grouping
checkbox
—
—
formula
group_by: a nested sub-group-by object (see below)
—
Formula group-by uses a nested group_by object that describes how to group the formula’s result type. The nested object does not include property_id (it inherits from the parent). Supported formula result types:
Subtask (sub-item) configuration controls how parent-child relationships are displayed in table views. This uses a self-referencing relation property to establish hierarchy.
Relation property ID used for parent-child nesting.
display_mode
enum
How sub-items are displayed. One of: "show" (hierarchical with toggles), "hidden" (parents with a count), "flattened" (sub-items with a parent indicator), "disabled" (no sub-item rendering).
filter_scope
enum
Which items are included when filtering. One of: "parents" (parent items only), "parents_and_subitems" (both), "subitems" (sub-items only).
toggle_column_id
string
Property ID of the column showing the expand/collapse toggle.
Cover configuration controls the image displayed at the top of each card in board and gallery views.
Report incorrect code
Copy
Ask AI
{ "type": "page_cover",}
Field
Type
Description
type
enum
Required. Source of the cover image. One of: "page_cover" (the page’s cover image), "page_content" (first image in page content), "property" (an image from a file property).
property_id
string
Property ID to use as the cover image source. Only used when type is "property".
When updating a view, you can pass null for any nullable configuration field to remove that setting. Only include the fields you want to change — omitted fields are left unchanged.Here are common scenarios:
Report incorrect code
Copy
Ask AI
// A table view currently has group_by set.// Pass null to remove grouping and return to a flat table.const updated = await notion.views.update({ view_id: "VIEW_ID", configuration: { type: "table", group_by: null, },});
Configuration updates use shallow merge — only the fields you include are changed, and omitted optional fields are preserved. The configuration field itself is optional (omit it to leave config unchanged). When present, you must include type and any fields marked as required for that view type (e.g., board views always require group_by, calendar/timeline views always require date_property_id). See Feature support by view type for which fields are required vs optional per view type.
Quick filters appear in the view’s filter bar and let users quickly toggle property-level filters without opening the full filter panel. In the API, quick_filters is a map where keys are property names or IDs, and values are filter conditions using the same shape as property filters but without the property field.
To add a new quick filter or update an existing one, include the property key with the new filter condition. Other existing quick filters are preserved.
Dashboard views let you arrange multiple widget views in a grid layout on a single database. Each widget is itself a view (table, board, list, etc.) that can reference a different data source.
To add a widget to a dashboard, create a view with view_id set to the dashboard’s ID instead of database_id. Each widget can use a different data_source_id. Dashboards support all view types as widgets except for other dashboards (no nested dashboards).
When adding a widget to a dashboard, you can control where it appears in the layout using the placement parameter. This is a discriminated union on the type field:
Variant
Fields
Description
new_row
type, optional row_index
Creates a new row containing the widget. If row_index is omitted, the new row is appended at the end. If provided, the new row is inserted at that 0-based position.
existing_row
type, row_index (required)
Adds the widget side-by-side to an existing row at the specified 0-based index. Column widths are automatically redistributed.
Report incorrect code
Copy
Ask AI
{ "placement": { "type": "new_row" }}
The placement parameter is only valid when view_id is provided (dashboard widget creation). It cannot be used with database_id. Each dashboard row supports a maximum of 4 widgets.
Widget views include a dashboard_view_id field that references their parent dashboard. Their parent.database_id always resolves to the underlying database, even though they are positioned inside a dashboard layout.
Use a view query to fetch pages using the view’s saved filter and sort configuration. This lets integrations reproduce what a user sees in the Notion UI for a particular view, without needing to manually reconstruct the filter/sort logic.View queries use a three-step pattern:
Create a query — executes the view’s filters/sorts and returns the first page of results along with a query_id.
Paginate results — use the query_id to fetch additional pages from the cached result set.
Delete the query (recommended) — free the cached result set when you’re done paginating.
Once you’ve finished paginating, delete the query to free the cached result set. This is optional — queries expire automatically after approximately 15 minutes — but recommended as good practice, especially if your integration runs queries frequently.
This endpoint is idempotent — calling it on an already-deleted or expired query still returns success.
Query expirationCached query results expire after a short TTL (approximately 15 minutes). If a query expires, create a new one. This caching approach provides stable pagination — results won’t shift between pages due to concurrent data changes.
View queries do not support stacking additional filters or sorts on top of the saved view definition. If you need different filter/sort criteria, create a new view (or update an existing one) and query that instead.