update_sp_item_properties() (experimental) to rename a file or folder or update the values of document library columns for an item. Field values are updated with update_sp_list_item(), so the same field name checks and formatting are used. (2026-10-14)fields argument to get_sp_item_properties() and update_sp_item_properties(). If fields = TRUE, the document library column values for the item are added as a fields element (a named list) or, if as_data_frame = TRUE, a fields list column with a 1 row data frame. (2026-10-14)sp_item_copy(), sp_item_move(), sp_dir_copy(), and sp_dir_move() (experimental) to copy and move SharePoint files and folders. The interface is based on fs::file_copy(), fs::file_move(), and fs::dir_copy(): if new_path is an existing folder, items are placed inside it. new_path can also be a SharePoint folder or library URL, and items can be copied (but not moved) to another drive or site. Set overwrite = TRUE to replace an existing item. By default, the copy functions wait for each copy to finish (wait = TRUE) so that a failed copy is reported. (2026-10-14)download_sp_item() (with multiple items) and upload_sp_items() now download or upload items in parallel if {carrier} and {mirai} are installed and mirai::daemons() are set. Folders are always uploaded one at a time. For batch downloads, the drive is now looked up once instead of for each item (unless items are SharePoint URLs). upload_sp_items() now checks that every file or src exists before uploading any files. (2026-10-13).batch argument to create_sp_list_items(), update_sp_list_items(), and delete_sp_list_items(). By default, items are now sent with Microsoft Graph $batch requests (up to 20 items per request), which was 7 to 9 times faster than a request per item in testing (and 10 to 15 times faster with mirai::daemons() set). Throttled requests are retried after the delay requested by the API. If any items fail, the other items are still sent and the error lists the failed items. Use .batch = FALSE or options(sharepointr.batch = FALSE) to send a request per item. Items created in a $batch request may not get IDs in the same order as the input data (use .batch = FALSE if the order of IDs matters). (2026-10-10)upload_sp_items() function (2024-06-24).update_sp_list_items() function and refactor update_sp_list_item() to use rlang::list2() and rlang::inject() which adds support for data frame inputs. (2024-08-10)display_nm argument to list_sp_list_items() allowing use of list display names as labels or replacements for field names in results. (2024-08-10)download_sp_list() (2024-10-10).create_column_definition() and related functions for creating lists equivalent to columnDefinition objects. (2025-05-02)update_sp_list() for limited updates to Microsoft List metadata. (2025-07-24){purrr} to imports to incorporate new purrr::in_parallel() function. Requires users have {carrier} and {mirai} installed and set workers using mirai::daemons(). (2025-07-25)read_sharepoint(). (2025-08-26)delete_sp_list_item() and delete_sp_list_items(). (2025-08-26)copy_column_definition_list() (2026-03-13)update_sp_list_lookup_items(). (2026-05-28)order_by and order_dir arguments to list_sp_list_items(). (2026-06-05)ms_drive_item inputs for dest argument of upload_sp_item() and upload_sp_items(). (2026-06-12)pull_sp_list_cols() (internal) to get a named index of list columns from get_sp_list_metadata() output matching a column type (e.g. "lookup" or "choice"), a column property (e.g. "required" or "hidden"), or a keep value ("all", "editable", or "external"). Supports both data frame and list metadata; get_sp_list_metadata() now uses it to filter columns. (2026-09-24)update_sp_list_item()/create_sp_list_item() now append @odata.type Collection hints so the Graph API accepts multi-value fields.delete_sp_list_item()/delete_sp_list_items() to accept a data frame for item_id (uses its id column).update_sp_list_items() to accept an unnamed list of named lists (one record per item, each with an .id element) as well as a data frame. Fields missing from a record are left unchanged. (2026-10-01)delete_sp_list_items() to accept an unnamed list of named lists (one record per item) for item_id. Add a .id argument to delete_sp_list_item() and delete_sp_list_items() to set the id column or element name. (2026-10-01)create_sp_list_items() to accept a list of named lists (one record per item) as well as a data frame. create_sp_list_items(), update_sp_list_items(), delete_sp_list_items(), update_sp_list_lookup_items(), and fmt_sp_list_lookup_items() now accept the same list inputs (a single record, where supported, or a named or unnamed list of records) with the same error message. (2026-10-10)strict argument to update_sp_list_items() (matching create_sp_list_items()) to error if any column or record field name doesn't match a list field. (2026-10-10)update_sp_list_person_items() for updating person or group columns (matched by email address using the site "User Information List") and fmt_sp_list_lookup_items() for formatting lookup or person columns as "{column_name}LookupId" values. These replace sp_user_id_as_lookup_id() and fmt_person_lookup_id_values(). (2026-10-01)create_sp_list_person_column() (experimental) for creating person or group columns. (2026-10-01)create_sp_list_lookup_column(), update_sp_list_lookup_items(), update_sp_list_person_items(), fmt_sp_list_lookup_items(), and list_sp_site_user_info() as experimental functions (no longer internal). create_sp_list_lookup_column() and the update functions now use a consistent argument order (data first for update functions and sp_list first for create functions), lookup_list can be a ms_list object, list name, or list URL (and must be in the same site as sp_list), and the sp_lookup_list argument is removed. update_sp_list_lookup_items() and fmt_sp_list_lookup_items() accept a data frame or list of records, support a different join column name for the lookup list (lookup_join_column) and case-insensitive matching (ignore_case), and list any values that can't be matched. (2026-10-01)user_type and filter arguments to list_sp_site_user_info(). Use user_type = "visible" to exclude hidden users. (2026-10-01)displayName, description, list for listInfo settings like template, and columns), with custom metadata (at the list or column level) passed through without validation. Read-only list properties (e.g. id, webUrl, createdDateTime, and parentReference) and column ids can be included as a reference to an existing list; they are never sent to SharePoint. get_sp_list_definition() and write_sp_list_yaml() include the stable read-only properties and column ids by default (read_only = "stable"). Add read_sp_list_yaml(), write_sp_list_yaml(), get_sp_list_definition(), as_sp_list_definition(), and sp_list_definition_table() (also used by an as.data.frame() method) as experimental functions. write_sp_list_yaml() keeps the comment header, column order, and custom metadata from an existing file (custom metadata in a definition passed to write_sp_list_yaml() takes precedence). A definition with no columns (e.g. a list with only the default Title column) is written as columns: []. An optional document start marker (---) can end the comment header, and write_sp_list_yaml(doc_start = ) controls whether one is written (by default, only if the existing file has one). read_sp_list_yaml() errors on a file with more than one YAML document. Requires {yaml12} (added to Suggests). (2026-10-09)compare_sp_list() and sync_sp_list() (experimental) to compare column definitions with an existing list and apply the changes. Only changed properties are sent. Changes the Graph API can't make (switching between single and multiple lines of text or single and multiple choice, and column validation) use the SharePoint REST API. Changes that may cause data loss are skipped unless allow_data_loss = TRUE, and changes that can't be made (e.g. changing the column type) are reported as blocked. (2026-10-09)list_sp_list_views(), get_sp_list_view(), create_sp_list_view(), update_sp_list_view(), and delete_sp_list_view() (experimental) for SharePoint list views. The Graph API doesn't support views, so these functions use the SharePoint REST API (with a delegated login) and the SP.View property names (e.g. ViewFields, ViewQuery, RowLimit). update_sp_list_view() only changes properties that differ from the existing view, and the default view can't be deleted. Add {jsonlite} to Imports for view formatting (custom_formatter). (2026-10-09)views key with SP.View properties. create_sp_list(definition = ) creates the views (a view titled "All Items" updates the default view), and get_sp_list_definition() and write_sp_list_yaml() include views if include_views = TRUE (default FALSE). View formatting is written as a YAML mapping. (2026-10-09)as_column_definition() to validate a column definition using Graph property names and column_validation() to create a column validation definition. (2026-10-09)create_column_definition() and the create_*_column() helpers now accept Graph property names passed to ... (e.g. allowMultipleLines = TRUE) and validate all properties. Unknown properties are now an error instead of being added to the definition. (2026-10-09)definition argument to create_sp_list() to create a list (name, description, template and other listInfo settings, and columns) from a definition or YAML file. A Title column updates the default title column, calculated columns are added after the list is created, and column validation is applied with the SharePoint REST API. list_name is now optional when definition is supplied. create_sp_list_column() also accepts definitions from read_sp_list_yaml(). (2026-10-09)compare_sp_list() and sync_sp_list() compare and update list views if a definition has a views element (or skip them with views = FALSE). Views are matched by Id or Title, the default view is set after other changes, and the current default view can't be deleted unless another view becomes the default. The results have an object column ("list", "column", or "view") and an id column (replacing column_id). (2026-10-09)compare_sp_list() and sync_sp_list() use a definition id and parentReference.siteId to get the list if sp_list isn't supplied, and error if the list id doesn't match the definition. They also compare and update the list displayName, description, hidden, and contentTypesEnabled settings. Formulas are compared after normalizing the changes SharePoint makes when saving a formula. (2026-10-09)create_sp_list() and create_sp_list_column() error if a new list column's name is longer than 32 characters (counting each space or special character as 7, e.g. _x0020_), since SharePoint cuts it without an error (document libraries allow longer names), and warn if a display name is longer than 255 characters (the limit on the column settings page; the Graph API accepts longer ones). compare_sp_list() reports adding a column with a long name as "blocked", so sync_sp_list() skips it. (2026-10-09)create_sp_drive() (experimental) to create a document library and return its drive as a ms_drive object. It wraps create_sp_list(template = "documentLibrary") and accepts the same list definitions, plus a folders argument. It doesn't create SharePoint Embedded containers (Graph fileStorageContainer), which need an app that owns a registered container type. (2026-10-13)update_sp_drive() and delete_sp_drive() (experimental) to change the display name or description of a document library or delete it. Renaming a library changes the drive name but not the library URL. delete_sp_drive() asks for confirmation by default and won't delete the site's default document library.folders key: a sequence of folder paths relative to the library root (parent folders are created as needed). create_sp_list() and create_sp_drive() create the folders, compare_sp_list() and sync_sp_list() add missing folders (never deleting any; skip them with folders = FALSE), and get_sp_list_definition() and write_sp_list_yaml() include folders if include_folders = TRUE (default FALSE). (2026-10-13)FileLeafRef and _ExtendedDescription) are left out of get_sp_list_definition() and only compared by compare_sp_list() if a definition includes them, a Title column updates the default title column of a new library, a view titled "All Documents" updates the default view of a new library, and library fields (e.g. LinkFilename) can be shown in a view without a warning. (2026-10-13)Fix write_sharepoint() saving {officer} rxlsx objects with readr::write_rds() and only matching a lowercase ".xlsx" extension for data frames (e.g. "data.XLSX" was written as a CSV file). (2026-10-10)
Fix update_sp_list_items() copying the calling environment (and any objects in it) to every parallel worker when mirai::daemons() are set. (2026-10-13)
Fix download_sp_item() erroring for a list of items with no dest (each item is now downloaded using the item name). (2026-10-13)
Fix create_sp_list_items(), update_sp_list_items(), and delete_sp_list_items() requiring {carrier} and {mirai} (and erroring or prompting to install them) even when items aren't sent in parallel. Items are now only sent in parallel with purrr::in_parallel() if both packages are installed and mirai::daemons() are set; otherwise, items are sent sequentially. {carrier} and {mirai} are now listed in Suggests and {purrr} 1.2.0 or later is now required. (2026-10-13)
Fix delete_sp_list_items(), create_sp_list_items(), and update_sp_list_items() failing for items with a temporary "Database is read only" error from SharePoint when sending many items with $batch requests. These requests, and requests with a 504 status, are now retried along with throttled requests (status 429 or 503). Requests without a Retry-After header are retried after an increasing delay (2, 4, 8, ... seconds, up to 60 seconds) and up to 5 times (instead of 3). The error for failed items now includes the HTTP status and Graph error code. (2026-10-13)
Fix Date values written to list date columns (e.g. with create_sp_list_item() or update_sp_list_items()) being stored as the previous day on SharePoint sites with a time zone west of UTC. Date values were sent as midnight UTC (e.g. "2026-10-13T00:00:00Z") and are now sent as a date with no time or offset (e.g. "2026-10-13"), which SharePoint stores using the site's time zone. POSIXct values are still sent as UTC date-times. (2026-10-13)
Fix sp_url_parse() decoding URL paths twice with {httr2} 1.1.0 or later, which changed file, folder, list, or library names that include a % character (e.g. "100%.xlsx"). sp_url_parse_path() now expects a decoded path (as returned by httr2::url_parse()). Requires {httr2} 1.1.0 or later. (2026-10-10)
Fix sp_url_parse() (and functions that accept a SharePoint URL) for list URLs with no view page (e.g. "https://contoso.sharepoint.com/sites/site-name/Lists/list-name"). (2026-10-10)
sp_url_parse() now errors if a site name can't be found in a URL, instead of returning a site URL with no site name that caused a "not found" error from the Graph API. (2026-10-10)
Fix compare_sp_list() and sync_sp_list() reporting a locale change for a column that was just created from the same definition (SharePoint returns locales like "en-US" for "en-us"). Locales are now compared ignoring case. (2026-10-10)
Fix item id handling for update_sp_list_items(), delete_sp_list_item(), and delete_sp_list_items(): item ids from a data frame, list of records, or vector are now checked (as whole numbers or non-empty strings) before any items are changed, so a missing or invalid id no longer stops a batch partway through. Item ids are sent as strings. delete_sp_list_item() errors for more than one item id or for unused arguments, and delete_sp_list_items() errors if both item_id and filter are supplied. (2026-10-10)
Fix update_sp_list_item() sending an empty update when only the .id field is left after dropping NA values (with .id other than "id") and erroring when no fields are supplied. (2026-10-10)
Fix create_sp_list_items() returning modified data (and both create_sp_list_items() and update_sp_list_items() returning empty data visibly): the input is now always returned invisibly and unmodified. create_sp_list_items() also checks data before any API calls or creating a list. (2026-10-10)
Fix update_sp_list_column() sending the whole column definition: only properties that differ from the existing column are sent. (2026-10-09)
Fix create_number_column() rejecting decimal max and min values. (2026-10-09)
Fix update_sp_list_items() and delete_sp_list_items() handling of named lists: a single named list record (with an .id element) or a named list of records is now supported. Previously, update_sp_list_items() only sent the first field from a named list, and delete_sp_list_items() used every element of a named list as an item id. Other named lists now error. (2026-10-06)
Fix list_sp_list_items() returning no items for a filtered query on a list with more than 5,000 items when the first page of results is empty. The Graph API evaluates these queries in batches, and an empty first page caused all later items to be dropped. (2026-10-05)
Fix updates to multi-value lookup and person or group columns: "{name}LookupId" values are now sent as a Collection(Edm.Int32) (lookup ID values are often returned as strings). (2026-10-01)
Fix delete_sp_list_item() erroring with a data frame item_id (the id value is now pulled from the data frame before checking arguments and getting the list item). (2026-10-01)
Fix update_sp_list_items() validating fields again for every item: fields are now validated once per call, so check_fields = FALSE is respected, and list column metadata is requested once per call (and shared for field validation and identifying multi-value fields) instead of for each item. create_sp_list_items() also shares a single list column metadata request for field validation and identifying multi-value fields. (2026-10-01)
Fix multi-select (multi-value) fields when creating or updating list items from a data frame with list-columns: create_sp_list_items()/update_sp_list_items() now unwrap list-column values, use list column definitions to send single or empty selections for multi-value columns as a Collection, and convert sfc columns to WKT for updates as well as creates. na_fields = "drop" now also drops empty values (e.g. character(0)) so existing values are left in place. (2026-10-01)
Fix bug where get_sp_list_item() only returned item ID, not the Microsoft365R::ms_list_item object (2024-08-10)
Fix bug where read_sharepoint() used readr::read_lines() for PowerPoint files. (2024-10-10)
Fix upload_sp_item() overwrite check validating against the source filename instead of the actual destination filename when dest renames the file.
Fix sp_dir_info() erroring (instead of warning) when recurse = TRUE and type = "file" are both supplied.
Fix sp_url_parse_path() erroring on drive names containing regex metacharacters (e.g. parentheses) by matching the drive name as a fixed string instead of interpolating it unescaped into a regex.
Fix list_sp_tasks()/get_sp_task() erroring when combining Planner tasks whose properties (e.g. dueDateTime, appliedCategories) are missing for some tasks but present for others, by no longer forcing a placeholder type for missing properties and by keeping dictionary-typed properties (assignments, appliedCategories) as consistent list columns. Also fixes a related crash in list_sp_group_members() for group members entirely missing an expected property.
get_sp_item(), get_sp_item_properties(), sp_dir_info() (and sp_dir_ls()), and upload_sp_item() (and write_sharepoint()) now use the Microsoft Graph shares API to get a file or folder from a SharePoint URL (a "Copy link" link, document URL, item URL, or document library URL). This supports items in any document library, links to items that have been moved, and URLs that can't be parsed (e.g. the webUrl for a file or a document library URL for a folder with an id query parameter). If the shares API request fails, the site, drive, and path are parsed from the URL as before. sp_dir_info() and upload_sp_item() now error if a URL is for a file instead of a folder, and upload_sp_item() no longer errors if dest is NULL and overwrite = FALSE. upload_sp_items() now supports a vector of destination URLs (including folders in different drives), finds the drive for a URL dest if drive isn't supplied, and gains overwrite, drive_name, drive_id, and drive arguments. Like upload_sp_item(), it now errors if a file already exists unless overwrite = TRUE. (2026-10-10)write_sharepoint() now errors if file is a shapefile (which writes more than one file, so only the ".shp" file was uploaded), and dest defaults to NULL (the top level of the drive) to match upload_sp_item(). (2026-10-10)list_sp_list_items() no longer includes the "@odata.etag" column, which the Graph API returns with the fields of each item, unless all_metadata = TRUE. (2026-10-10)read_sharepoint() to support zipped shapefiles. (2024-07-25).f argument in read_sharepoint(). (2024-10-10)data is empty for create_sp_list_items(), update_sp_list_items() and error if input item_id is length 0 for delete_sp_list_items(). (2026-01-06)sf data inputs for create_sp_list_items() (2026-05-27).{httr} and {AzureGraph} to Imports to re-implement an internal version of the list_items method for Microsoft365R::ms_list objects. (2026-06-05){dplyr} and {tidyselect} to Suggests in support of the update_sp_list_lookup_items() function. (2026-09-04){dplyr} and {tidyselect} from Suggests by using {vctrs} to match items in update_sp_list_lookup_items(). (2026-10-01)create_*_column() helpers no longer send default values for properties that aren't supplied, so SharePoint uses its own defaults. This changes the defaults for hidden (was FALSE), text_type (was "plain"), allow_text (was TRUE; SharePoint defaults to FALSE), display_as for choice (was "dropDownMenu") and date columns (was "default"), decimal_places (was "automatic"), format for date columns (was "dateOnly"; create_column_definition_list() still uses "dateOnly" for a "date" type), locale (was "en-us"), and allow_multiple_values for term columns (was TRUE). (2026-10-09)displayname (use display_name), decimals (use decimal_places), and allow_multiple (use allow_multiple_values for lookup and term columns or allow_multiple_selection for person or group columns). (2026-10-09)create_calculated_column() errors if format is supplied when output_type isn't "dateTime" (previously ignored) and returns the formula as a string. (2026-10-09)