Cesivi Server - REST API Reference¶
Version: 2.0
Last Updated: 2026-03-28
Base URL: http://localhost:5010 (default for main branch, see .branch-config.json)
Table of Contents¶
- Overview
- Authentication
- Web Operations
- List Operations
- List Item Operations
- File Operations
- Content Type Operations
- Field Operations
- Permission Operations
- Search Operations
- OData Query Parameters
- Error Codes
Overview¶
The Cesivi Server REST API provides SharePoint-compatible endpoints for managing sites, lists, items, files, and metadata. All endpoints follow the SharePoint REST API conventions.
Common Headers:
Accept: application/json;odata=verbose
Content-Type: application/json;odata=verbose
Authorization: Bearer {token} # or Basic, NTLM
Response Format: All successful responses return JSON with the following structure:
{
"d": {
// Response data here
}
}
Authentication¶
Cesivi Server supports multiple authentication methods:
- Bearer Token / OAuth 2.0 (Recommended for modern clients)
- Basic Authentication (Username/password)
- NTLM Authentication (Windows integrated auth)
- Forms Authentication (Cookie-based)
See IDENTITY_PROVIDERS.md for detailed configuration.
OAuth 2.0 / Azure AD Mock¶
Since PLAN-174, Cesivi includes a built-in Azure AD mock service for OAuth 2.0 authentication. This enables PnP PowerShell 2.x and other modern SharePoint clients to connect without requiring a real Azure AD tenant.
Supported Grant Types:
- authorization_code - Interactive login flow
- client_credentials - Service principal authentication
- refresh_token - Token refresh
Discovery Endpoint:
GET /.well-known/openid-configuration
Response includes issuer, authorization/token endpoints, supported grant types, and JWKS URI.
Token Endpoint:
POST /oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&
client_id=12345678-1234-1234-1234-123456789012&
client_secret=your-secret&
scope=https://cesivi.local/.default
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
Using Access Tokens:
GET /_api/web
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Accept: application/json
PnP PowerShell 2.x Example:
# Generate access token from mock Azure AD
$tokenResponse = Invoke-RestMethod -Method Post `
-Uri "https://localhost:5001/oauth2/v2.0/token" `
-Body @{
grant_type = "client_credentials"
client_id = "12345678-1234-1234-1234-123456789012"
client_secret = "mock-secret"
scope = "https://localhost:5001/.default"
}
$accessToken = ConvertTo-SecureString $tokenResponse.access_token -AsPlainText -Force
# Connect with access token
Connect-PnPOnline -Url "https://localhost:5001" -AccessToken $accessToken
# Use PnP cmdlets
Get-PnPWeb
Get-PnPList
For complete OAuth 2.0 documentation, see AUTHENTICATION.md.
Web Operations¶
Get Web¶
Retrieves the current web (site).
Endpoint: GET /_api/web
Query Parameters:
- $select - Select specific properties (e.g., Title,Description)
- $expand - Expand navigation properties (e.g., Lists)
Example Request:
GET /_api/web?$select=Title,Description,Url
Accept: application/json
Example Response:
{
"d": {
"Title": "Team Site",
"Description": "Collaborative team workspace",
"Url": "http://localhost:5000/Default/RootSite",
"Created": "2026-01-18T10:00:00Z",
"Id": "12345678-1234-1234-1234-123456789012"
}
}
Get Web Properties¶
Retrieves web properties collection.
Endpoint: GET /_api/web/allproperties
Example Request:
GET /_api/web/allproperties
Accept: application/json
Example Response:
{
"d": {
"vti_title": "Team Site",
"vti_defaultlanguage": "en-us"
}
}
List Operations¶
Create List¶
Creates a new list in the current web.
Endpoint: POST /_api/web/lists
Request Body:
{
"__metadata": { "type": "SP.List" },
"BaseTemplate": 100, // 100 = Generic List, 101 = Document Library, 107 = Tasks
"Title": "My List",
"Description": "List description"
}
Example Request:
POST /_api/web/lists
Content-Type: application/json
Accept: application/json
{
"__metadata": { "type": "SP.List" },
"BaseTemplate": 107,
"Title": "Project Tasks",
"Description": "Task tracking list"
}
Example Response:
{
"d": {
"Id": "87654321-4321-4321-4321-876543210987",
"Title": "Project Tasks",
"BaseTemplate": 107,
"ItemCount": 0,
"Created": "2026-01-18T11:00:00Z"
}
}
Response Codes:
- 201 Created - List created successfully
- 400 Bad Request - Invalid request body
- 409 Conflict - List with same title already exists
Get List¶
Retrieves a specific list by title or ID.
Endpoint: GET /_api/web/lists/getbytitle('{listTitle}')
Endpoint: GET /_api/web/lists(guid'{listId}')
Query Parameters:
- $select - Select specific properties
- $expand - Expand navigation properties (e.g., Fields,ContentTypes)
Example Request:
GET /_api/web/lists/getbytitle('Project Tasks')?$select=Title,ItemCount,Created
Accept: application/json
Example Response:
{
"d": {
"Title": "Project Tasks",
"ItemCount": 15,
"Created": "2026-01-18T11:00:00Z"
}
}
Get All Lists¶
Retrieves all lists in the current web.
Endpoint: GET /_api/web/lists
Query Parameters:
- $filter - Filter lists (e.g., Hidden eq false)
- $orderby - Sort lists (e.g., Title asc)
- $select - Select specific properties
Example Request:
GET /_api/web/lists?$filter=Hidden eq false&$orderby=Title&$select=Title,BaseTemplate,ItemCount
Accept: application/json
Example Response:
{
"d": {
"results": [
{
"Title": "Documents",
"BaseTemplate": 101,
"ItemCount": 42
},
{
"Title": "Project Tasks",
"BaseTemplate": 107,
"ItemCount": 15
}
]
}
}
Update List¶
Updates list properties.
Endpoint: PUT /_api/web/lists/getbytitle('{listTitle}')
Request Body:
{
"__metadata": { "type": "SP.List" },
"Description": "Updated description",
"EnableVersioning": true
}
Example Request:
PUT /_api/web/lists/getbytitle('Project Tasks')
Content-Type: application/json
Accept: application/json
{
"__metadata": { "type": "SP.List" },
"Description": "Updated task list",
"EnableVersioning": true
}
Response Codes:
- 200 OK - List updated successfully
- 404 Not Found - List not found
Delete List¶
Deletes a list.
Endpoint: DELETE /_api/web/lists/getbytitle('{listTitle}')
Example Request:
DELETE /_api/web/lists/getbytitle('Project Tasks')
Accept: application/json
Response Codes:
- 200 OK - List deleted successfully
- 404 Not Found - List not found
List Item Operations¶
Create Item¶
Creates a new item in a list.
Endpoint: POST /_api/web/lists/getbytitle('{listTitle}')/items
Request Body:
{
"__metadata": { "type": "SP.Data.{ListName}ListItem" },
"Title": "Item title",
"Status": "Active",
"Priority": 10
}
Example Request:
POST /_api/web/lists/getbytitle('Project Tasks')/items
Content-Type: application/json
Accept: application/json
{
"__metadata": { "type": "SP.Data.ProjectTasksListItem" },
"Title": "Complete documentation",
"Status": "Active",
"Priority": 10,
"AssignedTo": "user@example.com"
}
Example Response:
{
"d": {
"Id": 1,
"Title": "Complete documentation",
"Status": "Active",
"Priority": 10,
"Created": "2026-01-18T12:00:00Z",
"Modified": "2026-01-18T12:00:00Z"
}
}
Response Codes:
- 201 Created - Item created successfully
- 400 Bad Request - Invalid request body
Get List Items¶
Retrieves all items from a list with optional filtering, sorting, and paging.
Endpoint: GET /_api/web/lists/getbytitle('{listTitle}')/items
Query Parameters:
- $select - Select specific fields (e.g., Title,Status,Priority)
- $filter - Filter items (e.g., Status eq 'Active')
- $orderby - Sort items (e.g., Priority desc, Created asc)
- $top - Limit results (e.g., 10)
- $skip - Skip results for paging (e.g., 20)
- $expand - Expand navigation properties (e.g., Author,ContentType)
Example Request:
GET /_api/web/lists/getbytitle('Project Tasks')/items?$filter=Status eq 'Active'&$orderby=Priority desc&$top=10&$select=Id,Title,Status,Priority
Accept: application/json
Example Response:
{
"d": {
"results": [
{
"Id": 3,
"Title": "Critical bug fix",
"Status": "Active",
"Priority": 15
},
{
"Id": 1,
"Title": "Complete documentation",
"Status": "Active",
"Priority": 10
}
]
}
}
See Also: OData Query Parameters and ODATA_QUERY_GUIDE.md
Get Item by ID¶
Retrieves a specific item by ID.
Endpoint: GET /_api/web/lists/getbytitle('{listTitle}')/items({itemId})
Query Parameters:
- $select - Select specific fields
- $expand - Expand navigation properties
Example Request:
GET /_api/web/lists/getbytitle('Project Tasks')/items(1)?$select=Title,Status,Created,Author/Title&$expand=Author
Accept: application/json
Example Response:
{
"d": {
"Id": 1,
"Title": "Complete documentation",
"Status": "Active",
"Created": "2026-01-18T12:00:00Z",
"Author": {
"Title": "John Doe"
}
}
}
Update Item¶
Updates an existing item.
Endpoint: PUT /_api/web/lists/getbytitle('{listTitle}')/items({itemId})
Request Body:
{
"__metadata": { "type": "SP.Data.{ListName}ListItem" },
"Title": "Updated title",
"Status": "Completed"
}
Example Request:
PUT /_api/web/lists/getbytitle('Project Tasks')/items(1)
Content-Type: application/json
Accept: application/json
{
"__metadata": { "type": "SP.Data.ProjectTasksListItem" },
"Title": "Documentation complete",
"Status": "Completed"
}
Response Codes:
- 200 OK - Item updated successfully
- 404 Not Found - Item not found
Delete Item¶
Deletes an item.
Endpoint: DELETE /_api/web/lists/getbytitle('{listTitle}')/items({itemId})
Example Request:
DELETE /_api/web/lists/getbytitle('Project Tasks')/items(1)
Accept: application/json
Response Codes:
- 200 OK - Item deleted successfully
- 404 Not Found - Item not found
File Operations¶
Get Folder Contents¶
Retrieves files and folders from a document library.
Endpoint: GET /_api/web/lists/getbytitle('{libraryTitle}')/items
Query Parameters:
- $filter - Filter by FSObjType (0 = file, 1 = folder)
- $select - Select properties (FileLeafRef, FileRef, FileSize, etc.)
Example Request:
GET /_api/web/lists/getbytitle('Documents')/items?$filter=FSObjType eq 0&$select=Id,FileLeafRef,FileRef,File_x0020_Size
Accept: application/json
Content Type Operations¶
Content types define the metadata schema for items and documents. Cesivi Server supports content type inheritance, built-in SharePoint content types, and list-scoped content types.
Built-in Content Types¶
Cesivi Server includes 11 core SharePoint content types with proper inheritance chains:
| Content Type | ID | Parent | Description |
|---|---|---|---|
| Item | 0x01 |
(none) | Base content type for list items |
| Document | 0x0101 |
Item | Base content type for documents |
| Folder | 0x0120 |
Item | Folder content type |
| Event | 0x0102 |
Item | Calendar event |
| Task | 0x0108 |
Item | Task item |
| Issue | 0x0103 |
Item | Issue tracking item |
| Announcement | 0x0104 |
Item | Announcement item |
| Link | 0x0105 |
Item | URL link item |
| Wiki Page | 0x010108 |
Document | Wiki page document |
| Link to Document | 0x01010A |
Document | Document link |
| Document Library Folder | 0x0120D520 |
Folder | Document library folder |
Get Content Types¶
Retrieves all content types for a list or web.
Endpoint: GET /_api/web/lists/getbytitle('{listTitle}')/contenttypes
Endpoint: GET /_api/web/contenttypes
Example Request:
GET /_api/web/lists/getbytitle('Project Tasks')/contenttypes
Accept: application/json
Example Response:
{
"d": {
"results": [
{
"Id": "0x0100...",
"Name": "Item",
"Description": "Standard item content type",
"Group": "_Hidden"
}
]
}
}
Create Content Type (CSOM)¶
Create a new content type with inheritance using CSOM.
Example (C#):
using (var ctx = new ClientContext("http://localhost:5000/Default/RootSite"))
{
var web = ctx.Web;
// Get parent content type (Document)
var parentCT = web.ContentTypes.GetById("0x0101");
ctx.Load(parentCT);
ctx.ExecuteQuery();
// Create child content type
var newCT = web.ContentTypes.Add(new ContentTypeCreationInformation
{
Name = "CustomDocument",
Description = "Custom document type",
ParentContentType = parentCT,
Group = "Custom Content Types"
});
ctx.Load(newCT, ct => ct.Id, ct => ct.Name, ct => ct.Fields);
ctx.ExecuteQuery();
// Child automatically inherits parent's fields
Console.WriteLine($"Created: {newCT.Name} ({newCT.Id.StringValue})");
Console.WriteLine($"Inherited {newCT.Fields.Count} fields from parent");
}
Add Content Type to List (CSOM)¶
Add an existing web-level content type to a list.
Example (C#):
using (var ctx = new ClientContext("http://localhost:5000/Default/RootSite"))
{
var web = ctx.Web;
var list = web.Lists.GetByTitle("Documents");
// Get content type from web
var documentCT = web.ContentTypes.GetById("0x0101");
ctx.Load(documentCT);
ctx.ExecuteQuery();
// Add to list
list.ContentTypes.AddExistingContentType(documentCT);
ctx.Load(list.ContentTypes);
ctx.ExecuteQuery();
Console.WriteLine("Content type added to list");
// List fields are automatically updated with content type fields
}
Content Type Inheritance Chain¶
Content types inherit fields and properties from their parents. You can create multi-level inheritance:
Item (0x01)
└── Document (0x0101)
└── CustomDocument (0x010100abc...)
└── ProjectDocument (0x010100abc...00xyz...)
Example (C#):
// Level 1: Item (built-in)
var itemCT = web.ContentTypes.GetById("0x01");
// Level 2: Document (built-in, inherits from Item)
var docCT = web.ContentTypes.GetById("0x0101");
// Level 3: CustomDocument (inherits from Document)
var customDoc = web.ContentTypes.Add(new ContentTypeCreationInformation
{
Name = "CustomDocument",
ParentContentType = docCT,
Group = "Custom"
});
// Level 4: ProjectDocument (inherits from CustomDocument)
ctx.Load(customDoc);
ctx.ExecuteQuery();
var projectDoc = web.ContentTypes.Add(new ContentTypeCreationInformation
{
Name = "ProjectDocument",
ParentContentType = customDoc,
Group = "Custom"
});
ctx.Load(projectDoc, p => p.Fields);
ctx.ExecuteQuery();
// ProjectDocument inherits fields from all ancestors:
// Item → Document → CustomDocument → ProjectDocument
Content Type ID Format¶
Content type IDs follow a hierarchical pattern:
- Base: 0x01 (Item)
- Child: 0x01 + 01 = 0x0101 (Document)
- Grandchild: 0x0101 + 00abc123... = 0x010100abc123... (CustomDocument)
Each level adds a unique suffix to maintain the inheritance hierarchy.
Field Operations¶
Get List Fields¶
Retrieves all fields for a list.
Endpoint: GET /_api/web/lists/getbytitle('{listTitle}')/fields
Query Parameters:
- $filter - Filter fields (e.g., Hidden eq false)
- $select - Select properties
Example Request:
GET /_api/web/lists/getbytitle('Project Tasks')/fields?$filter=Hidden eq false&$select=Title,InternalName,TypeAsString
Accept: application/json
Example Response:
{
"d": {
"results": [
{
"Title": "Title",
"InternalName": "Title",
"TypeAsString": "Text"
},
{
"Title": "Status",
"InternalName": "Status",
"TypeAsString": "Choice"
}
]
}
}
Permission Operations¶
Get List Permissions¶
Retrieves role assignments for a list.
Endpoint: GET /_api/web/lists/getbytitle('{listTitle}')/roleassignments
Example Request:
GET /_api/web/lists/getbytitle('Project Tasks')/roleassignments
Accept: application/json
Search Operations¶
Search Query¶
Performs a search query across the site.
Endpoint: GET /_api/search/query
Query Parameters:
- querytext - Search query text
- rowlimit - Maximum results (default: 10)
- startrow - Start row for paging (default: 0)
Example Request:
GET /_api/search/query?querytext='project'&rowlimit=20
Accept: application/json
Example Response:
{
"d": {
"query": {
"PrimaryQueryResult": {
"RelevantResults": {
"RowCount": 3,
"Table": {
"Rows": {
"results": [
{
"Title": "Project Tasks",
"Path": "/Default/RootSite/Lists/ProjectTasks"
}
]
}
}
}
}
}
}
}
OData Query Parameters¶
Cesivi Server supports full OData v3 query syntax for filtering, sorting, and expanding data.
$filter¶
Filter items based on conditions.
Operators:
- eq - Equal to
- ne - Not equal to
- gt - Greater than
- ge - Greater than or equal to
- lt - Less than
- le - Less than or equal to
- and - Logical AND
- or - Logical OR
- not - Logical NOT
String Functions:
- startswith(field,'value') - Starts with
- endswith(field,'value') - Ends with
- substringof('value',field) - Contains
- tolower(field) - Convert to lowercase ✨ NEW
- toupper(field) - Convert to uppercase ✨ NEW
Date/Time Functions: ✨ NEW
- year(dateField) - Extract year from date
- month(dateField) - Extract month from date
- day(dateField) - Extract day from date
- datetime'2024-01-01T00:00:00Z' - Date literal for comparisons
Nested Functions: ✨ NEW
Functions can be nested for complex queries:
- startswith(tolower(Title),'project') - Case-insensitive search
Examples:
$filter=Status eq 'Active'
$filter=Priority ge 10
$filter=(Status eq 'Active' or Status eq 'Pending') and Priority gt 5
$filter=startswith(Title,'Project')
$filter=startswith(tolower(Title),'project') # Case-insensitive ✨ NEW
$filter=year(Created) eq 2024 # Items created in 2024 ✨ NEW
$filter=Created gt datetime'2024-01-01T00:00:00Z' # After Jan 1, 2024 ✨ NEW
$orderby¶
Sort items by one or more fields.
Syntax: $orderby=field1 [asc|desc][, field2 [asc|desc]]
Examples:
$orderby=Title
$orderby=Priority desc
$orderby=Status asc, Priority desc, Created asc
$select¶
Select specific fields to return (reduces payload size).
Syntax: $select=field1,field2,field3
Examples:
$select=Title,Status
$select=Id,Title,Created,Modified
$select=Title,Author/Title # Use with $expand
$expand¶
Expand related entities (navigation properties).
Syntax: $expand=property1[,property2]
Nested Query Options: ✨ NEW
You can now apply query options to expanded properties using parentheses:
Syntax: $expand=property($select=field1,field2;$filter=condition;$orderby=field;$top=N;$skip=M)
Examples:
$expand=Author
$expand=Author,ContentType
$expand=Author/Groups # Nested expand (multi-level)
$expand=Lists($select=Title,ItemCount) # Select specific properties ✨ NEW
$expand=Lists($filter=Hidden eq false) # Filter expanded items ✨ NEW
$expand=Lists($orderby=Title desc) # Sort expanded items ✨ NEW
$expand=Lists($top=5) # Limit expanded items ✨ NEW
$expand=Lists($select=Title;$filter=Hidden eq false;$orderby=Title) # Combined ✨ NEW
Note: Nested query options use semicolons (;) to separate multiple options within the parentheses.
$top and $skip¶
Limit and page results.
Syntax: $top=number and $skip=number
Examples:
$top=10 # First 10 items
$skip=20&$top=10 # Items 21-30 (page 3)
Combined Examples¶
Basic Query:
GET /_api/web/lists/getbytitle('Tasks')/items?
$filter=(Status eq 'Active' or Status eq 'Pending') and Priority ge 5&
$orderby=Priority desc, Created asc&
$top=20&
$skip=0&
$select=Id,Title,Status,Priority,Author/Title&
$expand=Author
Advanced Query with Functions: ✨ NEW
GET /_api/web/lists/getbytitle('Tasks')/items?
$filter=startswith(tolower(Title),'project') and year(Created) eq 2024&
$orderby=Priority desc&
$top=10&
$select=Id,Title,Status,Created&
$expand=Author($select=Title,Email)
Nested Query Options in $expand: ✨ NEW
GET /_api/web?
$expand=Lists($select=Title,ItemCount;$filter=Hidden eq false;$orderby=Title desc;$top=5)
See: ODATA_QUERY_GUIDE.md for comprehensive OData documentation.
Error Codes¶
| Code | Status | Description |
|---|---|---|
| 200 | OK | Request succeeded |
| 201 | Created | Resource created successfully |
| 204 | No Content | Request succeeded, no content returned |
| 400 | Bad Request | Invalid request syntax or parameters |
| 401 | Unauthorized | Authentication required or failed |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Resource not found |
| 409 | Conflict | Resource already exists or version conflict |
| 500 | Internal Server Error | Server error occurred |
Error Response Format:
{
"error": {
"code": "BadRequest",
"message": {
"lang": "en-US",
"value": "Invalid request body"
}
}
}
Additional Resources¶
- ODATA_QUERY_GUIDE.md - Comprehensive OData query syntax and examples
- CSOM_GUIDE.md - Client-side object model programming guide (if exists)
- DEPLOYMENT_GUIDE.md - Server deployment and configuration
- SECURITY_BEST_PRACTICES.md - Security configuration and hardening
Last Updated: 2026-03-28 Version: 2.0 For Support: See README.md