SharePoint REST API - Working with Views

I'm a .NET/M365 developer, trainer, author, MVP & MCT Alumni
This post covers views — the saved definitions that control what a user sees when they open a SharePoint list or library. You'll learn how to retrieve, create, update, and delete views through the REST API, and how to manage the fields a view displays.
Introduction
SP.View is the REST representation of a list or library view. A view defines:
Which fields (columns) are visible — controlled by
ViewFieldsWhich items appear and how they're sorted and grouped — controlled by
ViewQuery, a CAML query that can include<Where>,<OrderBy>, and<GroupBy>clausesHow many items appear per page — controlled by
RowLimitandPagedWhether subfolders are included — controlled by
Scope
A newly created list or library has at least one view, and normally one public view is designated as the default — the view SharePoint opens when a user navigates to the list without specifying another view. SharePoint Online REST can, however, leave a list without a default view; this edge case is covered later in the post.
The REST endpoint for a list's views is:
https://<tenant>.sharepoint.com/sites/<site>/_api/web/lists(guid'<listId>')/views
Authentication note: The raw HTTP examples use a SharePoint access token. With delegated authentication, the token represents a signed-in user and the operation must be permitted by both the delegated scope and that user's SharePoint permissions. With application (app-only) authentication, the token represents the Entra application and SharePoint evaluates its application permissions. For Entra app-only access to SharePoint REST, Microsoft documents certificate-based authentication; client-secret app-only tokens are not accepted by SharePoint REST. The legacy SharePoint ACS app-only model was retired on November 27, 2023 and stopped working on April 2, 2026. In SPFx, use
SPHttpClientinstead — it supplies the current user's SharePoint authentication context and manages request digests for write operations.
Before You Start: Headers and JSON Format
SharePoint's REST API defaults to OData v3. To use OData v4 — which is what SPFx's SPHttpClient uses by default — include the OData-Version: 4.0 header:
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Content-Type: application/json;odata.metadata=none (JSON-body requests only)
For a full explanation of OData versions, JSON format options, and how these headers interact, see Understanding SharePoint REST JSON Formats.
The SP.View Entity
The properties you'll use most often when working with views:
| Property | Type | Access | Description |
|---|---|---|---|
Id |
Guid |
Read-only | Unique identifier of the view. |
Title |
string |
Read/Write | Display name of the view, such as "All Items" or "Active Projects". |
DefaultView |
bool |
Read/Write | true if this is the list's default view. Setting this to true via MERGE automatically demotes the previous default. Only public views (PersonalView: false) can be set as the default — sending DefaultView: true on a personal view is silently ignored (MERGE returns 204 but DefaultView remains false) (validated against SharePoint Online). |
Hidden |
bool |
Read/Write | Whether the view is hidden from the view-selector UI. |
PersonalView |
bool |
Read-only | true if the view belongs to a specific user; false if it is a public/shared view. |
ServerRelativeUrl |
string |
Read-only | Server-relative URL of the view's ASPX page, e.g. /sites/marketing/Lists/Projects/AllItems.aspx. |
ViewType |
string |
Read-only | The type of view. Values include "HTML" (standard), "GRID" (datasheet), "CALENDAR", "RECURRENCE", "CHART", and "GANTT". |
ViewQuery |
string |
Read/Write | CAML query controlling which items appear and how they are sorted and grouped. Contains <Where>, <OrderBy>, and/or <GroupBy> elements directly — no outer <Query> element (validated against SharePoint Online). An empty string means no filtering, sorting, or grouping is defined by ViewQuery. |
RowLimit |
int32 |
Read/Write | Maximum number of items per page. Default is 30 (validated against SharePoint Online). |
Paged |
bool |
Read/Write | Whether results are split across pages when the count exceeds RowLimit. Defaults to false at creation (validated against SharePoint Online). |
Scope |
int32 |
Read/Write | Controls which folders and items the view includes. 0 = DefaultValue (items and folders in the current folder, default), 1 = Recursive (items recursively through subfolders without folder entries), 2 = RecursiveAll (items and folders recursively), 3 = FilesOnly (items in the current folder only without folder entries). |
ViewFields |
ViewFieldCollection |
Read-only | The ordered list of fields the view displays. The property reference itself is read-only — you cannot replace ViewFields by writing to the view entity — but the collection it points to is mutable through the sub-resource endpoint. See Managing View Fields below. |
CustomFormatter |
string |
Read/Write | JSON view-formatting definition for customizing how a modern list or library renders the view. |
ListViewXml |
string |
Read/Write | Sets the complete XML definition of the view — use care to preserve settings you do not intend to change. |
HtmlSchemaXml |
string |
Read-only | The full rendering schema XML for the view. Larger than ListViewXml; primarily useful for debugging. |
The following properties are available on SP.View but less frequently used in typical REST work. For modern SharePoint Online view customization, CustomFormatter (above) is the relevant property; properties like JSLink, Toolbar, and Method primarily support classic SharePoint rendering.
| Property | Type | Access | Description |
|---|---|---|---|
Aggregations |
string |
Read/Write | CAML/XML defining aggregate calculations (totals, averages, counts) displayed by the view. |
CalendarViewStyles |
string |
Read/Write | XML defining calendar-specific view style settings. Relevant for calendar-type views. Observed in the SharePoint Online REST API surface; not listed in the CSOM client reference. |
AggregationsStatus |
string |
Read/Write | Whether aggregates are displayed. Common values: "On" and "Off". |
BaseViewId |
string |
Read-only | Identifier of the base view template this view derives from, represented as an integer encoded as a string (e.g. "1"). |
ColumnWidth |
string |
Read/Write | Column-width information associated with the view. |
AssociatedContentTypeId |
string |
Read/Write | Content type ID associated with the view as a plain string value. Distinct from ContentTypeId, which serializes as a complex {"StringValue": "0x..."} object. Observed in the SharePoint Online REST API surface; not listed in the CSOM client reference. |
ContentTypeId |
ContentTypeId |
Read/Write | Content type with which the view is associated; content-type-specific views can be made available for folders of that content type. Serializes as {"StringValue": "0x..."} in the REST response — a complex type object, not a plain string. |
DefaultViewForContentType |
bool |
Read/Write | true if this is the default view for the associated content type. |
EditorModified |
bool |
Read/Write | Whether the view has been modified by an editor rather than remaining in its generated state. |
Formats |
string |
Read/Write | XML fragment containing legacy Datasheet/Grid view formatting settings (column widths, row height, text wrapping). The XML conforms to the ViewFormatDefinitions CAML schema. Distinct from CustomFormatter, which holds modern JSON view formatting. |
ImageUrl |
string |
Read-only | URL of the icon image associated with the view. |
IncludeRootFolder |
bool |
Read/Write | Whether the root folder is included when the view is rendered. |
JSLink |
string |
Read/Write | JavaScript file(s) for classic client-side rendering. Primarily a classic SharePoint feature. |
Method |
string |
Read/Write | XML defining the view method. Primarily relevant to classic SharePoint rendering. |
MobileDefaultView |
bool |
Read/Write | Whether this is the default view for the legacy mobile SharePoint experience. |
MobileView |
bool |
Read/Write | Whether the view is enabled as a mobile view. |
ModerationType |
string |
Read-only | How content approval is handled. Values: empty/null, "Moderator", "Contributor", "HideUnapproved". |
OrderedView |
bool |
Read-only | Whether items can be manually reordered in the view. |
PageRenderType |
int32 |
Read-only | The mechanism SharePoint uses to render the list page (numeric enum). Marked as beta in the OData schema — treat as unstable. |
ReadOnlyView |
bool |
Read-only | Whether the view definition is read-only and cannot normally be modified. |
RequiresClientIntegration |
bool |
Read-only | Whether the view requires client-integration functionality. |
ServerRelativePath |
ResourcePath |
Read-only | Resource-path representation of the view URL. Serializes as {"DecodedUrl": "/sites/..."}. Marked as beta in the OData schema — treat as unstable. |
StyleId |
string |
Read-only | Identifier of the view style applied. |
TabularView |
bool |
Read/Write | Whether the view uses standard tabular presentation. |
Threaded |
bool |
Read-only | Whether the view is a threaded view. Mainly applicable to discussion-board lists. |
Toolbar |
string |
Read/Write | XML or configuration describing the toolbar associated with the view. Primarily a classic-view feature. |
ToolbarTemplateName |
string |
Read-only | Name of the toolbar template used by the view. |
ViewData |
string |
Read/Write | Additional XML data used by specialized view types. |
ViewJoins |
string |
Read/Write | CAML <Joins> XML defining joins to other lists. Used together with ViewProjectedFields. |
ViewProjectedFields |
string |
Read/Write | CAML <ProjectedFields> XML defining fields from joined lists. |
VisualizationInfo |
SP.Visualization |
Read/Write | Visualization configuration for specialized visualization-capable view types. Marked as beta in the OData schema — treat as unstable. |
API Operations
Get All Views
With delegated access, the views collection returns all public views on the list plus any personal views owned by the signed-in user. It does not return personal views belonging to other users. With app-only access, only public views are returned — personal views are not visible to app-only tokens (validated against SharePoint Online).
GET https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views?$select=Id,Title,DefaultView,Hidden,PersonalView,ServerRelativeUrl,ViewType
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Response — 200 OK
{
"value": [
{
"DefaultView": true,
"Hidden": false,
"Id": "f3c0bdf3-2750-4a55-aa9a-8b0d48a7eaca",
"PersonalView": false,
"ServerRelativeUrl": "/sites/marketing/Lists/Projects/AllItems.aspx",
"Title": "All Items",
"ViewType": "HTML"
},
{
"DefaultView": false,
"Hidden": false,
"Id": "a1b2c3d4-5678-90ab-cdef-000000000001",
"PersonalView": false,
"ServerRelativeUrl": "/sites/marketing/Lists/Projects/ActiveProjects.aspx",
"Title": "Active Projects",
"ViewType": "HTML"
}
]
}
Get a Single View
By title:
GET https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views/getbytitle('All%20Items')
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
When a title contains an apostrophe, double it for the OData string literal before URL-encoding the title. URL-encoding alone does not escape the OData delimiter.
By GUID:
GET https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views('f3c0bdf3-2750-4a55-aa9a-8b0d48a7eaca')
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Response — 200 OK (abridged)
{
"DefaultView": true,
"Hidden": false,
"Id": "f3c0bdf3-2750-4a55-aa9a-8b0d48a7eaca",
"Paged": true,
"PersonalView": false,
"RowLimit": 30,
"Scope": 0,
"ServerRelativeUrl": "/sites/marketing/Lists/Projects/AllItems.aspx",
"Title": "All Items",
"ViewQuery": "",
"ViewType": "HTML"
}
The full response includes the view's scalar and complex SP.View properties. ViewQuery is an empty string when no filter, sort, or grouping query is defined — not null.
Get the Default View
When the list has a default view, SP.List exposes it through the DefaultView navigation property — without needing to know its title or GUID in advance:
GET https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/DefaultView
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Response — 200 OK — the full SP.View entity for the current default view, the same shape as any other view GET.
This is useful when you need to read or inspect the default view without first fetching the full views collection and filtering for the entry where DefaultView is true. You can combine it with $select to retrieve only the properties you need:
GET https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/DefaultView?$select=Id,Title,ViewQuery,RowLimit
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
When no default view exists — which can happen after deleting the default view through REST — the response is still 200 OK but the body is {"@odata.null":true}, the OData v4 representation of a null navigation property (validated against SharePoint Online).
Get View Fields
ViewFields is a navigation property that returns the fields displayed by the view. Access it as a sub-resource of the view:
GET https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views('f3c0bdf3-2750-4a55-aa9a-8b0d48a7eaca')/ViewFields
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Response — 200 OK
{
"SchemaXml": "<FieldRef Name=\"LinkTitle\" /><FieldRef Name=\"Status\" /><FieldRef Name=\"DueDate\" />",
"Items": ["LinkTitle", "Status", "DueDate"]
}
Items is an ordered array of field internal names — the fields the view displays, left to right. SchemaXml is the XML representation of the same data.
Create a View
Views are created by POST-ing to the views collection. Although CSOM's ViewCollection.Add takes an SP.ViewCreationInformation parameter, the REST endpoint validates the request body against SP.View directly — only Title is required.
POST https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Content-Type: application/json;odata.metadata=none
{
"Title": "Active Projects",
"RowLimit": 20,
"Paged": true,
"ViewQuery": "<Where><Eq><FieldRef Name=\"Status\" /><Value Type=\"Text\">Active</Value></Eq></Where><OrderBy><FieldRef Name=\"Title\" /></OrderBy>"
}
Response — 201 Created — the full SP.View entity is returned.
The POST body accepts SP.View property names directly (validated against SharePoint Online). Microsoft's SP.ViewCreationInformation type is documented as the creation parameter type, but the REST endpoint validates the body against SP.View — properties that exist only on SP.ViewCreationInformation and not on SP.View (such as Query, SetAsDefaultView, and ViewTypeKind) are rejected with 400 Bad Request. ViewFields and PersonalView are creation-time exceptions: both are accepted in the direct POST /views body even though they are read-only properties on an existing SP.View. ViewFields accepts a plain string array of field internal names drawn from SP.ViewCreationInformation. PersonalView accepts a boolean that creates a user-owned view rather than a public/shared view (validated against SharePoint Online).
When constructing CAML from dynamic values, XML-escape those values first, then JSON-serialize the resulting string for the request body. These are separate escaping layers.
Unprojected view responses can be large because SharePoint may include server-generated rendering data such as GridInitInfo. Use $select for reads when you do not need the full view definition.
The properties most useful to set at creation time:
| Property | Creation JSON type | Description |
|---|---|---|
Title |
string |
Name of the new view. Required. |
RowLimit |
int32 |
Maximum items per page. Defaults to 30 (validated against SharePoint Online). |
Paged |
bool |
Enable paging. Defaults to false — a view created without specifying Paged will not paginate regardless of RowLimit (validated against SharePoint Online). |
ViewQuery |
string |
Initial CAML query — no outer <Query> element. |
DefaultView |
bool |
Make this the list's default view on creation. Defaults to false, including when no default view currently exists — SharePoint does not auto-promote a newly created view in that state (validated against SharePoint Online). |
ViewFields |
string[] |
Initial fields as a JSON array of internal names, e.g. ["Title", "Status", "DueDate"]. When omitted and a default view exists, the new view inherits the fields of the current default view (validated against SharePoint Online). When no default view exists, the new view is created with an empty field list (validated against SharePoint Online). |
PersonalView |
bool |
Create a view owned by the signed-in user rather than a public/shared view. Defaults to false. Minimum delegated scope: AllSites.Write — see the permission note below. |
Other writable SP.View properties may also be accepted during creation, subject to property-specific validation.
Create a View Using views/add
The views/add endpoint is an alternative creation route that accepts SP.ViewCreationInformation properties. Its main advantage over the direct POST /views route is support for ViewTypeKind — the only way through REST to create a non-HTML view type such as Grid (datasheet) or Calendar (validated against SharePoint Online):
POST https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views/add
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Content-Type: application/json;odata.metadata=none
{
"parameters": {
"Title": "Active Projects - Grid",
"ViewTypeKind": 2048,
"Query": "<Where><Eq><FieldRef Name=\"Status\" /><Value Type=\"Text\">Active</Value></Eq></Where>",
"SetAsDefaultView": false,
"RowLimit": 50
}
}
Response — 201 Created — the full SP.View entity.
The body must wrap properties in a "parameters" object. The properties most useful for REST view creation (validated against SharePoint Online):
| Property | Type | Description |
|---|---|---|
Title |
string |
Name of the new view. Required. |
ViewTypeKind |
int32 |
Type of view to create, expressed as a ViewType enum value. The values 1 = HTML (standard), 2048 = Grid (datasheet), and 524288 = Calendar are validated examples, not an exhaustive list. |
Query |
string |
Initial CAML query — no outer <Query> element. Note the different property name: views/add accepts Query while direct POST /views requires ViewQuery. |
SetAsDefaultView |
bool |
Make this the list's default view on creation. views/add accepts SetAsDefaultView; direct POST /views uses DefaultView. |
RowLimit |
int32 |
Maximum items per page. |
Paged |
bool |
Enable paging. |
ViewFields |
string[] |
Initial fields as a JSON array of internal names. |
PersonalView |
bool |
Create a view owned by the signed-in user. |
The delegated scope floor is the same as the direct POST /views route: AllSites.Manage for public views, AllSites.Write for personal views (validated against SharePoint Online). The application permission floor for public views is likewise Sites.Manage.All (validated against SharePoint Online). For standard HTML views, the direct POST /views route is simpler — use views/add when you need to specify a non-HTML view type.
Update a View
Use a tunneled MERGE to update any writable SP.View property. Only include the properties you want to change:
POST https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views('a1b2c3d4-5678-90ab-cdef-000000000001')
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Content-Type: application/json;odata.metadata=none
X-HTTP-Method: MERGE
{
"RowLimit": 50,
"Paged": true,
"ViewQuery": "<Where><Eq><FieldRef Name=\"Status\" /><Value Type=\"Text\">Active</Value></Eq></Where><OrderBy><FieldRef Name=\"DueDate\" /></OrderBy>"
}
Response — 204 No Content
ViewQuery takes the CAML fragment directly — <Where>, <OrderBy>, <GroupBy> elements without an outer <Query> wrapper. This is the same format SharePoint returns when you read ViewQuery from an existing view.
Set as Default View
To make a view the default, MERGE it with "DefaultView": true. SharePoint automatically demotes the previous default view — no explicit unset is needed (validated against SharePoint Online):
POST https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views('a1b2c3d4-5678-90ab-cdef-000000000001')
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Content-Type: application/json;odata.metadata=none
X-HTTP-Method: MERGE
{
"DefaultView": true
}
Response — 204 No Content
Note: Only public views can be made the default view. Sending
DefaultView: trueon a personal view is silently ignored — the MERGE returns204 No Contentbut the view'sDefaultViewproperty remainsfalse(validated against SharePoint Online).
Set View XML
SetViewXml rewrites the entire view definition from a single XML string. ListViewXml is also exposed as a writable property on SP.View and can be updated via MERGE. The example below uses the dedicated SetViewXml method.
POST https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views('a1b2c3d4-5678-90ab-cdef-000000000001')/SetViewXml
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Content-Type: application/json;odata.metadata=none
{
"viewXml": "<View><Query><Where><Eq><FieldRef Name=\"Status\"/><Value Type=\"Text\">Active</Value></Eq></Where></Query><RowLimit>20</RowLimit></View>"
}
Response — 204 No Content (validated against SharePoint Online)
The viewXml value is the full view XML. SharePoint extracts the contents of the <Query> element and stores that fragment as ViewQuery — the outer <Query> wrapper is not retained. RowLimit and ViewFields are updated from the corresponding XML elements. Omitting <ViewFields> resets the view's field list to the base view template default rather than preserving the existing fields (validated against SharePoint Online).
Warning:
SetViewXmlreplaces the entire view definition. Malformed XML is rejected by SharePoint, but a syntactically valid yet incomplete definition can reset properties you intended to preserve.
Managing View Fields
The REST surface exposes four commonly useful mutation operations on ViewFields for managing which fields a view displays and their order. All four use POST. The three bodyless operations (addViewField, removeViewField, removeAllViewFields) require a Content-Length: 0 header — without it SharePoint Online returns 411 Length Required (validated). Most HTTP clients send Content-Length: 0 automatically on bodyless POSTs; raw curl without a -d argument does not.
Add a Field
Appends a field to the end of the view's field list:
POST https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views('a1b2c3d4-5678-90ab-cdef-000000000001')/ViewFields/addViewField('DueDate')
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Content-Length: 0
Response — 204 No Content
Remove a Field
Removes a field from the view's field list:
POST https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views('a1b2c3d4-5678-90ab-cdef-000000000001')/ViewFields/removeViewField('DueDate')
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Content-Length: 0
Response — 204 No Content
Reorder a Field
Changes a field's position in the view. The index is zero-based:
POST https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views('a1b2c3d4-5678-90ab-cdef-000000000001')/ViewFields/moveViewFieldTo
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Content-Type: application/json;odata.metadata=none
{
"field": "Status",
"index": 0
}
Response — 204 No Content
Remove All Fields
Clears all fields from the view. ViewFields.Items will be [] afterward. You would typically follow this with a series of addViewField calls to rebuild the field list from scratch:
POST https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views('a1b2c3d4-5678-90ab-cdef-000000000001')/ViewFields/removeAllViewFields
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Content-Length: 0
Response — 204 No Content
Delete a View
DELETE https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views('a1b2c3d4-5678-90ab-cdef-000000000001')
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Response — 204 No Content (validated against SharePoint Online)
SharePoint does not return an ETag for view resources, so If-Match is not needed and is omitted from the examples (validated against SharePoint Online). For clients or proxies that restrict HTTP methods to GET and POST, the tunneled form is an equivalent alternative:
POST https://contoso.sharepoint.com/sites/marketing/_api/web/lists(guid'a1b2c3d4-0001-0001-0001-000000000001')/views('a1b2c3d4-5678-90ab-cdef-000000000001')
OData-Version: 4.0
Accept: application/json;odata.metadata=none
Authorization: Bearer <token>
Content-Length: 0
X-HTTP-Method: DELETE
Content-Length: 0 is required on the tunneled POST form — SharePoint Online returns 411 Length Required without it. It is not needed for a native HTTP DELETE.
Warning: Deleting the default view succeeds — SharePoint Online does not prevent it. The list or library is left with no default view (validated against SharePoint Online).
Quick Reference
Headers
| Header | Notes |
|---|---|
Authorization: Bearer <token> |
Required for the raw HTTP OAuth examples in this post. SPFx SPHttpClient handles authentication automatically. |
Accept: application/json;odata.metadata=none |
Required for a JSON response. Omitting it causes SharePoint to return Atom XML. |
Content-Type: application/json;odata.metadata=none |
Required on requests with a JSON body (for example create, MERGE, SetViewXml, and moveViewFieldTo). |
OData-Version: 4.0 |
Activates OData v4 behavior. |
X-HTTP-Method: MERGE |
Tunnels an update over POST. |
X-HTTP-Method: DELETE |
Tunnels a delete over POST. |
Content-Length: 0 |
Required on bodyless POST requests (addViewField, removeViewField, removeAllViewFields, and the tunneled DELETE form) — SharePoint Online returns 411 Length Required without it (validated). Not required for a native HTTP DELETE. Most HTTP clients send it automatically on bodyless POSTs. |
Response Status Codes
| Operation | Status | Body |
|---|---|---|
| GET views / single view / ViewFields | 200 OK | JSON |
| Get default view | 200 OK | Full SP.View JSON, or {"@odata.null":true} when no default view exists |
Create view (POST /views) |
201 Created | Full SP.View entity |
Create view (POST /views/add) |
201 Created | Full SP.View entity |
| Update view (MERGE) | 204 No Content | Empty |
| Set default view (MERGE) | 204 No Content | Empty |
addViewField |
204 No Content | Empty |
removeViewField |
204 No Content | Empty |
moveViewFieldTo |
204 No Content | Empty |
removeAllViewFields |
204 No Content | Empty |
SetViewXml |
204 No Content | Empty |
| Delete view | 204 No Content | Empty |
Permission Requirements
The table below lists the minimum delegated and application permission scopes. Delegated scopes apply when calling with a Bearer token on behalf of a signed-in user; the minimum user permission level column shows the lowest built-in SharePoint permission level that permits the operation, followed by the lowest standard SharePoint group whose default permissions also permit it. Application permissions apply when calling without a signed-in user context (app-only). The application permissions in this table are permissions on the Office 365 SharePoint Online API, not the same-named Microsoft Graph permissions. An SPFx solution using SPHttpClient does not require you to grant these delegated or application scopes to the solution; it calls SharePoint as the current user, whose SharePoint permissions govern the operation. Delegated permission scope requirements were validated against SharePoint Online using a user with site Member access. The permission level requirements in the table come from Microsoft's documentation.
| Operation | Minimum delegated scope | Minimum user permission level | Minimum tenant-wide application permission |
|---|---|---|---|
| Read views (GET) | AllSites.Read |
Permission level: Read; Group: Visitor | Sites.Read.All |
| Create a public view | AllSites.Manage |
Permission level: Edit; Group: Member | Sites.Manage.All |
| Create a personal view | AllSites.Write |
Permission level: Contribute; Group: Member | Not covered — see note |
| Update a public view | AllSites.Manage |
Permission level: Edit; Group: Member | Sites.Manage.All |
| Update a personal view | AllSites.Write |
Permission level: Contribute; Group: Member | Not covered — see note |
| Delete a public view | AllSites.Manage |
Permission level: Edit; Group: Member | Sites.Manage.All |
| Delete a personal view | AllSites.Write |
Permission level: Contribute; Group: Member | Not covered — see note |
SetViewXml (public view) |
AllSites.Manage |
Permission level: Edit; Group: Member | Sites.Manage.All |
SetViewXml (personal view) |
AllSites.Write |
Permission level: Contribute; Group: Member | Not covered — see note |
| Manage view fields (public view) | AllSites.Manage |
Permission level: Edit; Group: Member | Sites.Manage.All |
addViewField (personal view) |
AllSites.Write |
Permission level: Contribute; Group: Member | Not covered — see note |
removeViewField, moveViewFieldTo, removeAllViewFields (personal view) |
Not yet validated — addViewField requires AllSites.Write |
Permission level: Contribute; Group: Member | Not covered — see note |
Note: The application permissions above are tenant-wide grants. For least-privilege app-only access to specific site collections, the SharePoint Sites.Selected application permission can be used instead. Sites.Selected consent alone does not grant access to any site — an explicit Read, Write, Manage, or FullControl role must be assigned on each target site collection.
Note:
AllSites.Writeis insufficient for public view create (401 Unauthorized), update (403 Forbidden), and delete (403 Forbidden) —AllSites.Manageis required for all three (validated against SharePoint Online). Personal views are an exception: creation, update, delete,SetViewXml, andaddViewFieldare validated withAllSites.Write; treat the other view-field mutations as requiring separate validation. Personal views belong to a specific signed-in user. App-only tokens return only public views (validated against SharePoint Online); app-only personal view write operations are not covered here.
Wrapping Up
Views are the lens through which users interact with list data. A few things to keep in mind as you build with the Views API:
ViewQuerytakes a CAML fragment directly —<Where>,<OrderBy>, and<GroupBy>elements without an outer<Query>wrapper. This applies to both reading and writing (validated against SharePoint Online).The direct
POST /viewsbody usesViewQuery, notQuery. DespiteSP.ViewCreationInformationdocumenting aQueryproperty, the direct endpoint validates the body againstSP.View. SendingQueryreturns 400. Theviews/addendpoint is the exception — it acceptsQueryasSP.ViewCreationInformationspecifies (validated against SharePoint Online).Setting
DefaultView: trueon a view via MERGE automatically demotes the previous default — no explicit unset of the old default is needed (validated). SharePoint Online also permits deleting the current default view through REST; the deletion succeeds and leaves the list or library with no default view (validated).On an existing view,
ViewFieldsis a navigation property, not a scalar. Manage it through the sub-resource endpoint (/views('id')/ViewFields) and its four POST operations, not by writing to the view entity directly.The bodyless
ViewFieldsoperations and the tunneled DELETE form all requireContent-Length: 0. A native HTTPDELETEdoes not. Most HTTP clients sendContent-Length: 0automatically on bodyless POSTs; rawcurlwithout a body does not.When creating a view with direct
POST /views, omitViewFieldsto inherit the fields of the current default view. When no default view exists, omittingViewFieldscreates the view with an empty field list. To specify initial fields explicitly, pass them as a plain JSON string array:["Title", "Status", "DueDate"].POST /views/addis the only REST route that creates non-HTML view types. PassViewTypeKindas aViewTypeenum value;1for HTML,2048for Grid (datasheet), and524288for Calendar are validated examples, not an exhaustive list. For standard HTML views the directPOST /viewsroute is simpler.
Happy coding!




