P4 REST API 2026.1 breaking changes

The P4 Server REST API is in Technology Preview and under active development. If you used P4 REST API 2025.2, review the following changes and required actions to make sure your application is not impacted when upgrading to P4 REST API 2026.1.

Features offered in Technology Preview are experimental and not guaranteed to always work as expected. If you have feedback and functionality suggestions, email techpreview@perforce.com.

Endpoint changes

The following GET endpoints have been renamed:

Previous endpoint New endpoint

./v0/file/metadata

./v0/file/revisions

./v0/changelist/{changelistNum}/files

./v0/changelist/{changelistNum}/revisions

These endpoints were renamed to better reflect the data they return, which is a list of file revisions.

The response structure is consistent with /file/revisions. However, for GET ./v0/changelist/{changelistNum}/revisions, the digest and fileSize fields are no longer included.

If required, fileSize can be retrieved using GET ./v0/file/revisions with the output=fileSize parameter.

Boolean value changes

Boolean values in GET ./v0/changelist/{changelistNum} are now returned as proper JSON booleans. Previously, these values were returned as string representations ("0" or "1").

For example:

Value entered: Interpreted as:

isPromoted: "1"

isPromoted: true

isUnsubmitted: "0"

isUnsubmitted: false

This is a breaking change for clients that perform string comparisons.

Action: Update any logic that checks for "0" or "1" to use boolean values (true or false) instead.

Request parameter changes

The way file specifications are passed in requests has changed. The previous fileSpecs parameter used a comma-separated list, which caused ambiguity because file specifications can contain commas. This made it difficult to reliably parse the input.

Using multiple fileSpec parameters removes this ambiguity and ensures all file specifications are handled correctly.

Example

Previously, multiple file specifications were passed as a single comma-separated parameter:

?fileSpecs=//depot/file1.txt,//depot/file2.txt

With this release, each file specification is now passed as a separate parameter:

?fileSpec=//depot/file1.txt&fileSpec=//depot/file2.txt

Response data changes

Response formats have been standardized to improve consistency and usability.

Error responses

Error responses now use a consistent, JSON-compliant structure. Previously, errors returned from different layers used different formats, and some responses used numbered properties instead of arrays.

All errors are now returned as a standard JSON object with an array of messages.

Copy
{
  "errors": [
    {
      "code": 822150148,
      "format": "Invalid option: -%option%.",
      "message": "Invalid option: -a.",
      "statusCode": 400
    }
  ],
  "parameters": { "option": "a" }
}

Structure simplification

Some response structures have been simplified:

Arrays now use standard JSON arrays instead of objects with numbered keys

Certain nested objects have been flattened (for example, jobs is now an array of strings).

Property naming

Response property names have been standardized to use camelCase. Previously, naming conventions varied across endpoints.

GET ./changelist/{changelistNum}

For GET ./changelist/{changelistNum}, the properties now use camelCase and jobs is a flat array of strings instead of a compound object.

Previous property New property

Change

change

Date

date

Client

client

User

user

Status

status

Type

type

Description

description

ImportedBy

importedBy

Identity

identity

Jobs

jobs

GET ./server/info

For GET ./server/info, the property names have been standardized to camelCase.

Previous property New property

ServerID

serverID

lbr.replication

lbrReplication

serverLicense-ip

serverLicenseIP

tzoffset

tzOffset

GET ./depot

For GET ./depot, the property names have been updated for consistency with future endpoints.

Previous property New property

name

depot

desc

description

time

date

Also, for GET ./depot, the extra field is no longer returned. It has been replaced with type-specific fields (suffix for spec depots and address for remote depots) to align with depot specification naming.

Depot type Previous field

New field

spec

extra

suffix

remote

extra

address

Other depot types

Not applicable

No change

These changes align the response with the corresponding depot specification fields.

Array response changes

Some responses previously represented arrays using numbered property names (for example, field0, field1) instead of standard JSON arrays.

This pattern has been removed. All such responses now return proper JSON arrays of objects.

Previous behavior

In some cases, repeated data (such as multiple users with a file open) was returned as a flat set of numbered properties:

Copy
{
  "otherAction0": "edit",
  "otherAction1": "edit",
  "otherChange0": "default",
  "otherChange1": "default",
  "otherOpen": "2",
  "otherOpen0": "bruno@bruno_ws",
  "otherOpen1": "gale@gale_ws"
}

New behavior

The same data is now returned as a structured array of objects:

Copy
{
  "otherOpen": [
    {
      "otherOpen": "bruno@bruno_ws",
      "otherAction": "edit",
      "otherChange": "default"
    },
    {
      "otherOpen": "gale@gale_ws",
      "otherAction": "edit",
      "otherChange": "default"
    }
  ]
}

This means:

  • Numbered properties (for example, field0, field1) are no longer returned.

  • Data is now grouped logically into arrays of objects.

  • This applies to all endpoints that previously returned pseudo-arrays.

Action: Update any code that reads values from numbered fields (otherOpen0, otherOpen1) or combines numbered fields into a list manually to instead read from standard JSON arrays (for example, iterate over the otherOpen array).