Skip to content

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

  1. Overview
  2. Authentication
  3. Web Operations
  4. List Operations
  5. List Item Operations
  6. File Operations
  7. Content Type Operations
  8. Field Operations
  9. Permission Operations
  10. Search Operations
  11. OData Query Parameters
  12. 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:

  1. Bearer Token / OAuth 2.0 (Recommended for modern clients)
  2. Basic Authentication (Username/password)
  3. NTLM Authentication (Windows integrated auth)
  4. 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