Cesivi Server - REST API¶
Home → Documentation → Features → REST API
Overview¶
The Cesivi Server implements a comprehensive REST API compatible with SharePoint Server Subscription Edition and SharePoint Online. The REST API provides 17+ endpoints with full OData v3 query support for modern web applications.
Status: ✅ PRODUCTION READY (98%+ coverage)
Base URL: /_api
Format: JSON (SharePoint Online compatible)
Performance: <5ms average response time
Quick Start¶
Basic Request¶
GET /_api/web HTTP/1.1
Host: localhost:5000
Accept: application/json;odata=verbose
Authorization: Basic YWRtaW46cGFzc3dvcmQ=
JavaScript Example¶
fetch('http://localhost:5000/_api/web/lists', {
headers: {
'Accept': 'application/json;odata=verbose',
'Authorization': 'Basic ' + btoa('admin:password')
}
})
.then(response => response.json())
.then(data => console.log(data.d.results));
PowerShell Example¶
$headers = @{
"Authorization" = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("admin:password"))
"Accept" = "application/json;odata=verbose"
}
Invoke-RestMethod -Uri "http://localhost:5000/_api/web/lists" -Headers $headers
Available Endpoints¶
Web & Site Operations¶
Get Current Web¶
GET /_api/web
Returns metadata for the current web (site).
Response:
{
"d": {
"__metadata": { "type": "SP.Web" },
"Id": "8ee3228a-72b3-4674-8282-f07e0f4a2db2",
"Title": "Root Web",
"Url": "http://localhost:5000",
"ServerRelativeUrl": "/",
"Description": "Mock SharePoint Root Web",
"Created": "2025-01-01T00:00:00Z",
"LastItemModifiedDate": "2025-11-15T00:00:00Z",
"Language": 1033,
"WebTemplate": "STS",
"Configuration": 0
}
}
Get Site Collection¶
GET /_api/site
Returns site collection metadata.
Response:
{
"d": {
"__metadata": { "type": "SP.Site" },
"Id": "12345678-1234-1234-1234-123456789012",
"Url": "http://localhost:5000",
"ServerRelativeUrl": "/"
}
}
Get Subwebs¶
GET /_api/web/webs
Returns child webs (subsites).
Response:
{
"d": {
"results": [
{
"__metadata": { "type": "SP.Web" },
"Id": "abc-123-def-456",
"Title": "Subsite 1",
"Url": "http://localhost:5000/subsite1"
}
]
}
}
Get Current User¶
GET /_api/web/currentuser
Returns information about the currently authenticated user.
Response:
{
"d": {
"__metadata": { "type": "SP.User" },
"Id": 1,
"LoginName": "i:0#.w|domain\\admin",
"Title": "Administrator",
"Email": "admin@localhost"
}
}
Get Context Info¶
POST /_api/contextinfo
Returns form digest and context information.
Response:
{
"d": {
"GetContextWebInformation": {
"FormDigestValue": "0x1234567890ABCDEF...",
"FormDigestTimeoutSeconds": 1800,
"WebFullUrl": "http://localhost:5000"
}
}
}
List Operations¶
Get All Lists¶
GET /_api/web/lists
Returns all lists in the current web.
Response:
{
"d": {
"results": [
{
"__metadata": { "type": "SP.List" },
"Id": "abc-123-def-456",
"Title": "Documents",
"BaseType": 1,
"BaseTemplate": 101,
"Hidden": false,
"ItemCount": 10,
"Description": "Shared document library",
"Created": "2025-01-01T00:00:00Z"
}
]
}
}
Get List by Title¶
GET /_api/web/lists/getbytitle('Documents')
Returns a specific list by title.
Response:
{
"d": {
"__metadata": { "type": "SP.List" },
"Id": "abc-123-def-456",
"Title": "Documents",
"BaseType": 1,
"Description": "Shared document library",
"ItemCount": 10
}
}
Get List by GUID¶
GET /_api/web/lists(guid'{list-id}')
Returns a specific list by GUID.
Create List¶
POST /_api/web/lists
Request Body:
{
"__metadata": { "type": "SP.List" },
"Title": "New List",
"Description": "My new list",
"BaseTemplate": 100,
"AllowContentTypes": true
}
Update List¶
POST /_api/web/lists/getbytitle('Documents')
Headers: X-HTTP-Method: MERGE, IF-MATCH: *
Request Body:
{
"__metadata": { "type": "SP.List" },
"Description": "Updated description"
}
Delete List¶
DELETE /_api/web/lists/getbytitle('Documents')
Headers: IF-MATCH: *
List Item Operations¶
Get List Items¶
GET /_api/web/lists/getbytitle('Documents')/items
Returns all items in a list.
Response:
{
"d": {
"results": [
{
"__metadata": { "type": "SP.Data.DocumentsItem" },
"Id": 1,
"Title": "Document 1",
"FileLeafRef": "document1.docx",
"Modified": "2025-11-15T10:00:00Z",
"Created": "2025-11-01T10:00:00Z",
"Author": { "Title": "John Doe" }
}
]
}
}
Get Item by ID¶
GET /_api/web/lists/getbytitle('Documents')/items(1)
Returns a specific item by ID.
Create Item¶
POST /_api/web/lists/getbytitle('Documents')/items
Request Body:
{
"__metadata": { "type": "SP.Data.DocumentsItem" },
"Title": "New Document",
"FileLeafRef": "newdoc.docx"
}
Update Item¶
POST /_api/web/lists/getbytitle('Documents')/items(1)
Headers: X-HTTP-Method: MERGE, IF-MATCH: *
Request Body:
{
"__metadata": { "type": "SP.Data.DocumentsItem" },
"Title": "Updated Title"
}
Delete Item¶
DELETE /_api/web/lists/getbytitle('Documents')/items(1)
Headers: IF-MATCH: *
File Operations¶
Get File Metadata¶
GET /_api/web/getfilebyserverrelativeurl('/Shared Documents/file.docx')
Returns file metadata.
Response:
{
"d": {
"__metadata": { "type": "SP.File" },
"Name": "file.docx",
"ServerRelativeUrl": "/Shared Documents/file.docx",
"Length": 12345,
"TimeCreated": "2025-11-01T10:00:00Z",
"TimeLastModified": "2025-11-15T10:00:00Z",
"Title": "My Document"
}
}
Download File¶
GET /_api/web/getfilebyserverrelativeurl('/Shared Documents/file.docx')/$value
Returns the file content as binary stream.
Upload File¶
POST /_api/web/getfolderbyserverrelativeurl('/Shared Documents')/files/add(url='newfile.docx',overwrite=true)
Headers: Content-Type: application/octet-stream
Body: Binary file content
Delete File¶
DELETE /_api/web/getfilebyserverrelativeurl('/Shared Documents/file.docx')
Headers: IF-MATCH: *
Check Out File¶
POST /_api/web/getfilebyserverrelativeurl('/Shared Documents/file.docx')/checkout
Check In File¶
POST /_api/web/getfilebyserverrelativeurl('/Shared Documents/file.docx')/checkin(comment='My changes',checkintype=1)
checkintype values:
- 0 = MinorCheckIn
- 1 = MajorCheckIn
- 2 = OverwriteCheckIn
Undo Check Out¶
POST /_api/web/getfilebyserverrelativeurl('/Shared Documents/file.docx')/undocheckout
Folder Operations¶
Get Folder Metadata¶
GET /_api/web/getfolderbyserverrelativeurl('/Shared Documents/Subfolder')
Get Folder Files¶
GET /_api/web/getfolderbyserverrelativeurl('/Shared Documents')/files
Get Subfolders¶
GET /_api/web/getfolderbyserverrelativeurl('/Shared Documents')/folders
Create Folder¶
POST /_api/web/folders
Request Body:
{
"__metadata": { "type": "SP.Folder" },
"ServerRelativeUrl": "/Shared Documents/New Folder"
}
Delete Folder¶
DELETE /_api/web/getfolderbyserverrelativeurl('/Shared Documents/Folder')
Headers: IF-MATCH: *
OData Query Support¶
$select (Field Selection)¶
Select specific fields to return:
GET /_api/web/lists?$select=Title,ItemCount
Response:
{
"d": {
"results": [
{ "Title": "Documents", "ItemCount": 10 },
{ "Title": "Tasks", "ItemCount": 5 }
]
}
}
$filter (Filtering)¶
Filter results based on criteria:
GET /_api/web/lists?$filter=Hidden eq false and ItemCount gt 5
Supported Operators:
- Comparison: eq, ne, gt, ge, lt, le
- Logical: and, or, not
- String: startswith, endswith, substringof
Examples:
# Equals
$filter=Title eq 'Documents'
# Not equals
$filter=Hidden ne true
# Greater than
$filter=ItemCount gt 10
# Starts with
$filter=startswith(Title,'Doc')
# Contains (substring)
$filter=substringof('test',Title)
# Multiple conditions
$filter=Hidden eq false and ItemCount gt 5
$orderby (Sorting)¶
Sort results:
GET /_api/web/lists?$orderby=Title asc
GET /_api/web/lists?$orderby=ItemCount desc
GET /_api/web/lists?$orderby=Title asc,ItemCount desc
$top (Limit Results)¶
Limit number of results:
GET /_api/web/lists?$top=10
$skip (Pagination)¶
Skip results (for pagination):
GET /_api/web/lists?$skip=20&$top=10
$expand (Expand Related Entities)¶
Expand related entities:
GET /_api/web?$expand=Lists
GET /_api/web/lists?$expand=Fields
GET /_api/web/lists/getbytitle('Documents')/items?$expand=Author,Editor
Combined Queries¶
Combine multiple query parameters:
GET /_api/web/lists/getbytitle('Documents')/items?$select=Title,Created&$filter=Created gt datetime'2025-01-01T00:00:00Z'&$orderby=Created desc&$top=10
User & Group Operations¶
Get Site Users¶
GET /_api/web/siteusers
Get User by ID¶
GET /_api/web/siteusers/getbyid(1)
Get User by Email¶
GET /_api/web/siteusers/getbyemail('user@domain.com')
Ensure User¶
POST /_api/web/ensureuser
Request Body:
{
"logonName": "i:0#.w|domain\\user"
}
Get Site Groups¶
GET /_api/web/sitegroups
Get Group by ID¶
GET /_api/web/sitegroups/getbyid(5)
Create Group¶
POST /_api/web/sitegroups
Request Body:
{
"__metadata": { "type": "SP.Group" },
"Title": "New Group",
"Description": "Group description"
}
Add User to Group¶
POST /_api/web/sitegroups/getbyid(5)/users
Request Body:
{
"__metadata": { "type": "SP.User" },
"LoginName": "i:0#.w|domain\\user"
}
Search Operations¶
Execute Search Query¶
GET /_api/search/query?querytext='test'
Query Parameters:
- querytext: Search query
- rowlimit: Max results (default: 500)
- startrow: Start row for pagination
- selectproperties: Fields to return
- refiners: Facet refinement
Response:
{
"d": {
"query": {
"PrimaryQueryResult": {
"RelevantResults": {
"RowCount": 2,
"TotalRows": 2,
"Table": {
"Rows": {
"results": [
{
"Cells": {
"results": [
{ "Key": "Title", "Value": "Document 1" },
{ "Key": "Path", "Value": "/Shared Documents/doc1.docx" }
]
}
}
]
}
}
}
}
}
}
}
Limitations & Workarounds¶
❌ Not Supported¶
OData v4 Features:
- $count=true (use OData v3 __count instead)
- $search (use $filter with substringof)
- $apply (use multiple queries)
Advanced Features: - Workflow REST APIs (deprecated in SharePoint) - Social feed APIs (use Microsoft Graph instead) - SharePoint Online-specific endpoints (Hub Sites, Compliance)
⚠️ Partial Support¶
Batch Requests:
- $batch endpoint exists but has limited testing
- Prefer individual requests for reliability
Navigation Properties:
- Some complex $expand paths may not work
- Use multiple requests if expansion fails
✅ Workarounds¶
Missing OData Features → Use SOAP:
# If REST query fails, use SOAP Lists service:
$svc = New-WebServiceProxy -Uri "http://localhost:5000/_vti_bin/lists.asmx?WSDL"
$items = $svc.GetListItems("Documents", $query, $viewFields, ...)
Complex Queries → Break into Multiple Requests:
// Instead of complex $expand:
const lists = await fetch('/_api/web/lists').then(r => r.json());
const items = await Promise.all(
lists.d.results.map(list =>
fetch(`/_api/web/lists(guid'${list.Id}')/items`).then(r => r.json())
)
);
Error Handling¶
Error Response Format¶
{
"error": {
"code": "-1, System.ArgumentException",
"message": {
"lang": "en-US",
"value": "List 'InvalidList' does not exist at site with URL 'http://localhost:5000'."
}
}
}
Common HTTP Status Codes¶
| Code | Meaning | Common Cause |
|---|---|---|
200 |
OK | Request succeeded |
201 |
Created | Resource created successfully |
400 |
Bad Request | Invalid request body or query |
401 |
Unauthorized | Missing or invalid authentication |
404 |
Not Found | List, item, or file not found |
409 |
Conflict | Resource already exists (create) |
412 |
Precondition Failed | IF-MATCH etag mismatch |
500 |
Internal Server Error | Server error (check logs) |
Best Practices¶
1. Use $select for Better Performance¶
Only request fields you need:
// ❌ Bad - returns all fields
fetch('/_api/web/lists/getbytitle("Documents")/items')
// ✅ Good - only returns needed fields
fetch('/_api/web/lists/getbytitle("Documents")/items?$select=Title,Created')
2. Use Batch Requests for Multiple Operations¶
Reduce round-trips with batch requests:
POST /_api/$batch
Content-Type: multipart/mixed; boundary=batch_abc123
--batch_abc123
Content-Type: application/http
Content-Transfer-Encoding: binary
GET /_api/web/lists HTTP/1.1
Accept: application/json
--batch_abc123--
3. Handle Pagination for Large Results¶
Use $top and $skip for pagination:
async function getAllItems(listTitle) {
const pageSize = 100;
let skip = 0;
let allItems = [];
while (true) {
const url = `/_api/web/lists/getbytitle('${listTitle}')/items?$top=${pageSize}&$skip=${skip}`;
const response = await fetch(url).then(r => r.json());
const items = response.d.results;
if (items.length === 0) break;
allItems.push(...items);
skip += pageSize;
}
return allItems;
}
4. Cache Form Digest¶
Cache form digest to avoid unnecessary requests:
let formDigestValue = null;
let formDigestExpiry = null;
async function getFormDigest() {
if (formDigestValue && formDigestExpiry > Date.now()) {
return formDigestValue;
}
const response = await fetch('/_api/contextinfo', { method: 'POST' })
.then(r => r.json());
formDigestValue = response.d.GetContextWebInformation.FormDigestValue;
formDigestExpiry = Date.now() + 1800000; // 30 minutes
return formDigestValue;
}
See Also¶
- SOAP Services - Legacy web services
- CSOM - Client-Side Object Model
- PnP PowerShell - PowerShell cmdlets
- API Reference - Complete endpoint documentation
- Known Limitations - API constraints
Last Updated: November 15, 2025 API Version: OData v3 Compatibility: SharePoint 2019, SharePoint Online
Navigation: Home | Documentation | Features | REST API