API Version 2 - Changelog - Cloud


2026-06

Fixes

Rotate image page now persists the rotation

POST /Repositories/{repositoryId}/Entries/{entryId}/Document/Pages/{pageNumber}/Image/Rotate previously returned 200 OK without actually saving the rotation — the page's imageRotationAngle was left unchanged and the page still rendered in its original orientation. The rotation is now persisted, so a subsequent read (e.g. ListPageInfos) reflects the new imageRotationAngle and viewers display the rotated page.

Entries

Entry Introspection

GET /Repositories/{repositoryId}/Entries/{entryId} gains two opt-in query parameters. Both are comparatively expensive to compute, so they are omitted from the response unless explicitly requested:

  • includeChildInfo=true (folder entries) — returns a childInfo object { hasChildren, childCount, folderCount, documentCount, shortcutCount } describing the folder's immediate children (total plus per-type counts). Counts are for immediate children only — recursive/whole-subtree counts are intentionally not offered. For folder tree navigation, prefer optimistic lazy expansion (load children on demand) over requesting this per node.
  • includeTotalSize=true (document entries) — returns totalDocumentSize, the document's full stored size (electronic document plus page image/text/locations/thumbnail data and attachments), as opposed to electronicDocumentSize, which is just the source file.

Field Definitions

Field Definition Administration

Repository administrators can now create and manage metadata field definitions over REST. Previously the FieldDefinitions surface was read-only.

  • POST /Repositories/{repositoryId}/FieldDefinitions — create a field definition. name and fieldType are required; the request also accepts the writable definition attributes (description, length, format/formatPattern, constraint/constraintError, currency, defaultValue) and behavior flags (isIndexed, isIndexedForReporting, isMultiValue, isRequired, warnIfBlank, hideListValues, autoExtract), plus an optional properties extended key-value bag and initial listValues for List-type fields. Returns the created definition.
  • PATCH /Repositories/{repositoryId}/FieldDefinitions/{fieldId} — partial update of writable properties. Only supplied properties change; null leaves a property unchanged and "" clears a string property. fieldType cannot be changed here (use ChangeType) and list values are managed through the dedicated ListValues resource.
  • DELETE /Repositories/{repositoryId}/FieldDefinitions/{fieldId} — delete a field definition. Returns 409 if the field is still referenced by templates or assigned to entries.
  • GET / PUT /Repositories/{repositoryId}/FieldDefinitions/{fieldId}/ListValues — read or wholesale-replace the pick-list values of a List-backed field. PUT preserves client-supplied order; an empty array clears the list. Non-list fields are rejected with 400.
  • GET /Repositories/{repositoryId}/FieldDefinitions/{fieldId}/ContainingTemplates — list the template definitions that include this field.
  • GET /Repositories/{repositoryId}/FieldDefinitions/{fieldId}/AssignedEntryCount — count of entries currently using this field.
  • GET / PATCH /Repositories/{repositoryId}/FieldDefinitions/{fieldId}/Properties — read or update the field's extended properties bag (a string key-value store for integration metadata and application-specific configuration that persists with the field definition).

Destructive Operations

Administrators can now consolidate or convert existing field definitions:

  • POST /Repositories/{repositoryId}/FieldDefinitions/Merge — merges two or more existing field definitions into a new field. onConflict (Fail (default), MakeMultivalue, UseFirstField) controls how per-entry value conflicts are resolved; UseFirstField discards conflicting values and requires allowDataLoss = true. Optional removeFromTemplates removes the source fields from any templates that contain them; autoRename requests a non-conflicting name when newFieldName collides (best-effort — honoring is repository-version-dependent). The source field definitions themselves are preserved — only their per-entry values are migrated to the new merged field; delete the sources explicitly afterward if no longer needed.
  • POST /Repositories/{repositoryId}/FieldDefinitions/{fieldId}/ChangeType — converts an existing field definition to a different newFieldType. The conversion may reset type-specific configuration (length, constraint, format), clear list items when leaving the List type, and drop default values or per-entry values that don't fit the new type. allowDataLoss = true is required for any conversion the server treats as lossy; the only conversions exempt are the explicit safe widenings Date → DateTime, ShortInteger → LongInteger, ShortInteger → Number, and LongInteger → Number (and only when no other lossy condition applies).

Template Definitions

Template Definition Administration

Repository administrators can now create and manage metadata template definitions over REST. Previously the TemplateDefinitions surface was read-only.

  • POST /Repositories/{repositoryId}/TemplateDefinitions — create a template definition. name is required; optional description, color, isAutoAssignable, and an initial fields array (each entry: fieldName, optional isRequired, optional localDescription). Initial fields are applied to the template after creation; if a field assignment fails mid-list the template is created with the partial set (reported, not rolled back).
  • PATCH /Repositories/{repositoryId}/TemplateDefinitions/{templateId} — partial update of template properties (name, description, color, isAutoAssignable). null leaves a property unchanged; for color, an explicit null clears the color.
  • DELETE /Repositories/{repositoryId}/TemplateDefinitions/{templateId} — delete a template definition. Returns 409 if the template is still assigned to entries.
  • GET /Repositories/{repositoryId}/TemplateDefinitions/{templateId}/AssignedEntryCount — count of entries currently assigned this template.
  • GET / PATCH /Repositories/{repositoryId}/TemplateDefinitions/{templateId}/Properties — read or update the template's extended properties bag.

Template Field Management

  • POST /Repositories/{repositoryId}/TemplateDefinitions/{templateId}/Fields — add a field to a template. Optional position (1-based) inserts at that position; otherwise the field is appended. Optional per-template isRequired and localDescription.
  • PATCH /Repositories/{repositoryId}/TemplateDefinitions/{templateId}/Fields/{fieldName} — update a field's per-template properties (isRequired, localDescription). The per-template required flag is distinct from the field definition's repository-level required flag.
  • DELETE /Repositories/{repositoryId}/TemplateDefinitions/{templateId}/Fields/{fieldName} — remove a field from the template. Field values already assigned to entries are unaffected.
  • POST /Repositories/{repositoryId}/TemplateDefinitions/{templateId}/Fields/Move — reorder a field within the template via fieldName + newPosition (1-based).

The existing GET template endpoints now additionally surface isAutoAssignable on the template and localDescription on each template field.


2026-05

Entries

Document Page Manipulation

A Laserfiche document is a composite of an electronic document (optional), image pages, and text pages. New endpoints expose per-page image and text content independently:

  • POST /Repositories/{repositoryId}/Entries/{entryId}/Document/Pages — create pages (image, text, both, or empty). Optional pageNumber inserts at position; otherwise appends. Optional generateText triggers OCR.
  • PUT /Repositories/{repositoryId}/Entries/{entryId}/Document/Pages — replace all pages in a single call (one lock, one auto-version).
  • PUT /Repositories/{repositoryId}/Entries/{entryId}/Document/Pages/{pageNumber} — overwrite image part, text part, or both of an existing page. At least one of imageFile or request.text required.
  • DELETE /Repositories/{repositoryId}/Entries/{entryId}/Document/Pages — delete a range or all pages.
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Document/Pages/Move — reorder pages within the same document via a pageRange + destinationPageNumber.
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Document/Pages/Copy — copy pages from one document to another. The pageRange is limited to 500 distinct pages per request.
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Document/Pages/{pageNumber}/Image/Rotate — rotate the image of a single page by 90/180/270 degrees.
  • GET /Repositories/{repositoryId}/Entries/{entryId}/Document/Pages/{pageNumber}/Image — retrieve per-page image content as binary.
  • GET /Repositories/{repositoryId}/Entries/{entryId}/Document/Pages/{pageNumber}/Text — retrieve per-page text content.
  • GET /Repositories/{repositoryId}/Entries/{entryId}/Document/Pages — list page metadata (image/text presence). Optional pageRange filters a subset.
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Document/GenerateText — trigger OCR across all image pages.

Document Lifecycle

  • POST /Repositories/{repositoryId}/Entries({parentEntryId})/Folder/Import now accepts an optional imageFiles parameter (up to 10 files, 100 MB aggregate) and an optional generateImagePagesText flag (default true) that runs OCR on image pages after import. Omitting file — or supplying a zero-length file — creates an empty document with no electronic document and no pages.
  • PATCH /Repositories/{repositoryId}/Entries/{entryId}/Document — unified additive update for the electronic document, metadata (fields, tags, links, template), and image pages. At least one of file, imageFiles, or metadata must be provided. Metadata is additive; imageFiles are appended; a non-empty file replaces the edoc. Zero-length file is rejected with 400 — use DELETE .../Document/Edoc to remove the edoc explicitly.
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Document/UpdateUploadedParts — chunked async counterpart for large files. Assembles previously uploaded parts (from CreateMultipartUploadUrls) and applies optional metadata.
  • DELETE /Repositories/{repositoryId}/Entries/{entryId}/Document/Edoc — remove the electronic document while preserving pages and metadata.
  • PUT /Repositories/{repositoryId}/Entries({entryId})/Template and DELETE /Repositories/{repositoryId}/Entries({entryId})/Template — assign or remove an entry's template. Applies to all entry types.

Document Lock and Version Control

  • POST /Repositories/{repositoryId}/Entries/{entryId}/Document/Lock — create a persistent lock on a document with optional comment and extent (Page, Edoc, Metadata, or All; default All). Persistent locks survive session disconnect and server restart.
  • GET /Repositories/{repositoryId}/Entries/{entryId}/Document/Lock — retrieve the current lock state (lock token, owner, comment, extent, creation timestamp, active status).
  • DELETE /Repositories/{repositoryId}/Entries/{entryId}/Document/Lock — unlock the current user's lock, or unlock another user's lock administratively via ?lockToken={token}.
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Document/VersionControl — put a document under version control. Required before checkout.
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Document/CheckOut — check out a document. Optional lock (default true) auto-acquires a persistent lock; optional comment attaches a message.
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Document/CheckIn — check in a document, creating a new version. Optional unlock (default true) releases any persistent lock as part of the check-in.
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Document/UndoCheckOut — undo a check-out without creating a new version.

Document Response Fields

GET /Repositories/{repositoryId}/Entries/{entryId} responses for document entries now include the following document-specific fields alongside the existing pageCount, electronicDocumentSize, isCheckedOut, and isUnderVersionControl:

  • isLocked — whether the document has a persistent lock.
  • lockedBy — display name of the persistent lock holder (nullable).
  • isLockedByAnotherUser — true if locked by a user other than the caller.
  • currentVersion — version number (0 if not under version control).
  • checkedOutBy — display name of the user who checked out the document (nullable).
  • isCheckedOutByAnotherUser — true if checked out by a user other than the caller.

2026-03

Other

Bug Fixes

  • Fixed the Start Menu shortcut for Laserfiche API Server to now point to the correct documentation.

Maintenance

  • Updated rate limits for import and export APIs. Exact limits can be found in the documentation.

2025-08

Maintenance

  • Added support for various languages including Japanese and German for error messages

2025-07

Maintenance

  • Removed v2-alpha endpoints

Security Updates

  • Updated vulnerable dependencies.
  • Updated to .NET 8

2024-08

Maintenance

  • Removed v1-alpha endpoints

2024-01

Entries

The following API is updated to always return entryType, even if the OData $select query options is used and it doesn't include entryType:

  • GET /Repositories/{repositoryId}/Entries/{entryId}

Searches

The following API is updated to always return entryType, even if the OData $select query options is used and it doesn't include entryType:

  • GET /Repositories/{repositoryId}/Searches/{taskId}/Results

SimpleSearches

The following API is updated to always return entryType, even if the OData $select query options is used and it doesn't include entryType:

  • POST /Repositories/{repositoryId}/SimpleSearches
2023-10: Initial Release - Changes from V1

The following compares the Laserfiche Repository API V1 with V2 at time of release.

AuditReasons

Features

[BREAKING] Restructured the response body to return a single wrapped list for the following API:

  • GET /Repositories/{repoId}/AuditReasons
Entries

Features

[NEW] Added export APIs:

  • POST /Repositories/{repositoryId}/Entries/{entryId}/Export
    • This API is used to export an entry and returns a response with a download link, if successful. This API may time out if the operation takes longer than 60 seconds. Use the below long operation asynchronous /ExportAsync if you run into this restriction.
  • POST /Repositories/{repositoryId}/Entries/{entryId}/ExportAsync
    • This API is used to start an export task and returns a task id. This API follows a long operation pattern and does not have the restrictions in the /Export API. See below to learn more about the long operations.

[BREAKING] Removed export related APIs:

  • HEAD /Repositories/{repoId}/Entries/{entryId}/Laserfiche.Repository.Document/edoc
  • GET /Repositories/{repoId}/Entries/{entryId}/Laserfiche.Repository.Document/edoc
  • POST /Repositories/{repoId}/Entries/{entryId}/Laserfiche.Repository.Document/GetEdocWithAuditReason

[NEW] Added import APIs:

  • POST /Repositories/{repositoryId}/Entries/{entryId}/Folder/Import
    • This API is used to import a file and returns a response indicating if it was successful. This API has a maximum file size limit of 100MB and may time out if the operation takes longer than 60 seconds. Use the below long operation asynchronous /ImportAsync if you run into this restriction.
  • POST /Repositories/{repositoryId}/Entries/CreateMultipartUploadUrls
    • This API is used to request URLs for uploading a large file in chunks. After the file chunks are written to the URLs, the import task can be started by calling the /ImportUploadedParts API.
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Folder/ImportUploadedParts
    • This API is used to start an import task and returns a task id. This API has a maximum file size limit of 64GB, and API follows a long operation pattern. Furthermore, it does not have the restrictions in the /Import API. See below to learn more about the long operations.

[BREAKING] Removed import API:

  • POST /Repositories/{repoId}/Entries/{parentEntryId}/{fileName}

[BREAKING] Renamed the request body properties, renamed the response body properties, and changed the success status code to 202 Accepted for the following API:

  • DELETE /Repositories/{repoId}/Entries/{entryId}

[BREAKING] Moved the autoRename query parameter to the request body for the following API:

  • PATCH /Repositories/{repoId}/Entries/{entryId}

[BREAKING] Removed the Laserfiche.Repository. in the URL and changed the response to return an Entry for the following APIs:

  • DELETE /Repositories/{repoId}/Entries/{entryId}/Laserfiche.Repository.Document/edoc
  • DELETE /Repositories/{repoId}/Entries/{entryId}/Laserfiche.Repository.Document/pages

[BREAKING] Removed the Laserfiche.Repository. in the URL, renamed the formatFields query parameter, and restructured the fields portion of the response body for the following API:

  • GET /Repositories/{repoId}/Entries/{entryId}/Laserfiche.Repository.Folder/children

[BREAKING] Removed the Laserfiche.Repository. in the URL and moved the autoRename query parameter to the request body for the following API. Additionally, moved the copy functionality out to a new POST /Repositories/{repositoryId}/Entries/{entryId}/Folder/Copy API.

  • POST /Repositories/{repoId}/Entries/{entryId}/Laserfiche.Repository.Folder/children

[BREAKING] Removed the Laserfiche.Repository. in the URL, moved the autoRename query parameter to the request body, renamed the response body properties, and changed the success status code to 202 Accepted for the following API:

  • POST /Repositories/{repoId}/Entries/{entryId}/Laserfiche.Repository.Folder/CopyAsync

[BREAKING] Renamed the formatValue query parameter and restructured the response body for the following API:

  • GET /Repositories/{repoId}/Entries/{entryId}/fields

[BREAKING] Restructured the request body and restructured the response body for the following API:

  • PUT /Repositories/{repoId}/Entries/{entryId}/fields

[BREAKING] Restructured the request body and renamed the response body properties for the following API:

  • PUT /Repositories/{repoId}/Entries/{entryId}/links

[BREAKING] Renamed the response body properties for the following APIs:

  • GET /Repositories/{repoId}/Entries/{entryId}/links
  • GET /Repositories/{repoId}/Entries/{entryId}/tags
  • PUT /Repositories/{repoId}/Entries/{entryId}/tags

[BREAKING] Restructured the request body for the following API:

  • PUT /Repositories/{repoId}/Entries/{entryId}/template
LinkDefinitions

[BREAKING] Renamed the response body properties for the following APIs:

  • GET /Repositories/{repoId}/LinkDefinitions
  • GET /Repositories/{repoId}/LinkDefinitions/{linkTypeId}
Repositories

Features

[BREAKING] Restructured the response body to return a wrapped list with renamed properties for the following API:

  • GET /Repositories
Searches

Features

[BREAKING] Removed APIs for getting a search status and cancelling a search. Use the new v2 Tasks APIs for getting the status and cancelling a set of one or more Tasks, including Search.

  • GET /Repositories/{repoId}/Searches/{searchToken}
  • DELETE /Repositories/{repoId}/Searches/{searchToken}

[BREAKING] Changed the URL to POST /Repositories/{repositoryId}/Searches/SearchAsync, renamed the response body properties, and changed the success status code to 202 Accepted for the following API:

  • POST /Repositories/{repoId}/Searches

[BREAKING] Renamed the formatFields query parameter and restructured the fields portion of the response body for the following API:

  • GET /Repositories/{repoId}/Searches/{taskId}/Results
ServerSession

Features

[BREAKING] In the past, it was necessary to call POST /Repositories/{repoId}/ServerSession/Create first before making any other API calls. This is no longer required as any API can be called after receiving an access token. As a result, the following APIs have been removed.

  • POST /Repositories/{repoId}/ServerSession/Create
  • POST /Repositories/{repoId}/ServerSession/Refresh
  • POST /Repositories/{repoId}/ServerSession/Invalidate
SimpleSearches

Features

[BREAKING] Renamed the formatFields query parameter and restructured the fields portion of the response body for the following API. Additionally, 200 OK status code is returned with an empty array instead of 204 No Content when no search results are found.

  • GET /Repositories/{repoId}/SimpleSearches
TagDefinitions

Features

[BREAKING] Renamed the response body properties for the following APIs:

  • GET /Repositories/{repoId}/TagDefinitions
  • PUT /Repositories/{repoId}/TagDefinitions/{tagId}
Tasks

Features

[NEW] Added APIs for getting the status and cancelling a set of one or more Tasks.

  • GET /Repositories/{repositoryId}/Tasks
  • DELETE /Repositories/{repositoryId}/Tasks

[BREAKING] Removed APIs for getting the status and cancelling a single Task.

  • GET /Repositories/{repoId}/Tasks/{operationToken}
  • DELETE /Repositories/{repoId}/Tasks/{operationToken}

[BREAKING] Getting the status of a Task, now uses the long polling technique and could return the result immediately (e.g. if the long operation failed or completed successfully) or after at most 60 seconds.

TemplateDefinitions

Maintenance

[BREAKING] Changed the /Fields portion of the URL to /FieldDefinitions for the following APIs:

  • GET /Repositories/{repoId}/TemplateDefinitions/{templateId}/Fields
  • GET /Repositories/{repoId}/TemplateDefinitions/Fields
Long Operations

Features

[BREAKING] Applies to the following APIs:

  • DELETE /Repositories/{repositoryId}/Entries/{entryId}
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Folder/CopyAsync
  • POST /Repositories/{repositoryId}/Entries/{entryId}/ExportAsync
  • POST /Repositories/{repositoryId}/Entries/{entryId}/Folder/ImportUploadedParts
  • POST /Repositories/{repositoryId}/Searches/SearchAsync

Long operations will return a taskId property instead of a token. The taskId will still be used by the Tasks APIs for getting the status and cancelling long operations.

Error handling has now been centralized. Long operations will return a taskId property immediately if possible, and errors (e.g. validation errors or the errors that may occur during the execution of the operation) can be found by checking the status of the long operation using GET /Repositories/{repositoryId}/Tasks. Previously in v1, errors could be returned when creating the API or when checking the status of the long operation.

Other

Features

OAuth 2.0 scopes are mandatory in v2 and will issue a 403 Forbidden response if your access token does not have the correct scopes. See the documentation in the Swagger Playground for the required OAuth scope needed to access each API. Learn more about OAuth scopes here.

Properties with null value are omitted during response serialization, if the corresponding property is a Collection type, or a Nullable Integral type.