Common Services API¶
Common Services is the session management and system information layer of P21. It is the foundation for all UI-based API operations — every call to the Interactive API or Transaction API depends on an active session created through Common Services.
Base URL: https://{your-server}/uiserver0/ui/common/v1/
Overview¶
Common Services provides six categories of functionality:
| Category | Purpose |
|---|---|
| Sessions | Create, manage, and close P21 user sessions |
| Admin | Server and session administration (privileged) |
| Alerts | Retrieve system and user alerts |
| Info | Discover available service endpoints |
| Server Info | Retrieve P21 server version and configuration |
| Tasks | Retrieve the current user's task list |
Sessions¶
Sessions are the central concept in Common Services. A session represents an authenticated user context on the P21 application server. All UI-based API calls (Interactive, Transaction) must be associated with an active session.
Session Endpoints¶
| URI | Method | Operation | Description |
|---|---|---|---|
/sessions/ | POST | CreateSession | Create a new session and authenticate |
/sessions/ | DELETE | CloseSession | Terminate the current session |
/sessions/ | GET | GetAllSessions | List all open sessions (admin) |
/sessions/allstates | GET | GetAllSessionStates | Retrieve full state of all active sessions |
/sessions/favorites | GET | GetFavorites | Retrieve user's saved favorites |
/sessions/favorites | PUT | SetFavorites | Update user's saved favorites |
/sessions/favorites | DELETE | DeleteFavorites | Remove user's saved favorites |
/sessions/ping | POST | PingSession | Send a keep-alive to prevent timeout |
/sessions/preference/{name} | GET | GetPreference | Read a named session preference |
/sessions/preference/{name} | POST | CreatePreference | Create a new session preference |
/sessions/preference/{name} | PUT | SetPreference | Update an existing session preference |
/sessions/state | GET | GetSessionState | Get current session state details |
/sessions/variables/{key} | GET | GetVariable | Read a session variable by key |
/sessions/variables/{key} | POST | SetVariable | Write a session variable by key |
/sessions/window/all | GET | GetAllWindows | List all windows open in this session |
/sessions/windowmenu | DELETE | CloseWindowByMenu | Close windows matching a menu ID |
POST /sessions/ — Create Session¶
Creates a new authenticated session on the P21 application server.
Authentication: Basic (Authorization: Basic {base64(username:password)})
Request Body — JSON:
{
"SessionType": "User",
"WorkstationID": "MyIntegration-Prod",
"PrintMode": "Browser",
"SessionTimeout": 2147483647,
"ClientPlatformApp": "OrderSyncService",
"OnBehalfOf": ""
}
Request Body — XML (full schema):
<UserParameters xmlns="http://schemas.datacontract.org/2004/07/P21.UI.Service.Model.Common.V1">
<ClientPlatformApp>String content</ClientPlatformApp>
<OnBehalfOf>String content</OnBehalfOf>
<PrintMode>Browser</PrintMode>
<ResponseWindowHandlingEnabled>true</ResponseWindowHandlingEnabled>
<SessionTimeout>2147483647</SessionTimeout>
<SessionType>User</SessionType>
<TestingOptions>
<AutoOpenPortals>true</AutoOpenPortals>
<BypassApplicationRoleSecurity>true</BypassApplicationRoleSecurity>
<DisableCustomSoftware>true</DisableCustomSoftware>
<DisableDynachange>true</DisableDynachange>
<OverrideConfigNo>2147483647</OverrideConfigNo>
<Password>String content</Password>
<Programmer>true</Programmer>
</TestingOptions>
<WWMSOptions>
<BinID>String content</BinID>
<CompanyID>String content</CompanyID>
<LocationID>2147483647</LocationID>
<WwmsOnly>true</WwmsOnly>
</WWMSOptions>
<WorkstationID>String content</WorkstationID>
</UserParameters>
SessionType Values¶
| Value | Description |
|---|---|
User | Standard interactive user session. Most common for integrations. |
Auto | Background automation session. Does not support interactive windows. |
AutoInteractive | Automated session that can also open windows. |
Scheduler | Reserved for P21 scheduler processes. |
PrintMode Values¶
| Value | Description |
|---|---|
Browser | Print output directed to browser/web. Default for API use. |
Local | Routes print output to a local printer. |
Network | Routes print output to a network printer. |
TestingOptions¶
Development Use Only
TestingOptions bypass security controls and alter application behavior. Never use these in production environments.
| Option | Type | Description |
|---|---|---|
DisableCustomSoftware | bool | Prevents Business Rules and custom event hooks from running. |
DisableDynachange | bool | Disables Dynachange UI customizations. |
BypassApplicationRoleSecurity | bool | Bypasses P21 role-based security checks. |
Programmer | bool | Enables programmer/diagnostic mode. |
AutoOpenPortals | bool | Controls automatic portal opening behavior. |
OverrideConfigNo | int | Overrides the session configuration number. |
Password | string | Testing password override. |
WWMSOptions¶
| Option | Type | Description |
|---|---|---|
CompanyID | string | Company ID for WWMS session scope. |
BinID | string | Target bin identifier. |
LocationID | int | Target location identifier. |
WwmsOnly | bool | Restricts session to WWMS operations only. |
Response: Returns a session object containing the session token and initial session state.
Example — C#:
var credentials = Convert.ToBase64String(
Encoding.ASCII.GetBytes($"{username}:{password}"));
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", credentials);
var body = JsonSerializer.Serialize(new
{
SessionType = "User",
WorkstationID = "OrderSync-Prod",
PrintMode = "Browser",
SessionTimeout = int.MaxValue
});
var response = await client.PostAsync(
"https://{server}/uiserver0/ui/common/v1/sessions/",
new StringContent(body, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
DELETE /sessions/ — Close Session¶
Terminates the current session and releases the session license slot.
Always Close Sessions
P21 user licenses limit the number of concurrent sessions per user. Failure to close sessions will exhaust session capacity and prevent the user from logging into the P21 client. Always close sessions in a finally block or IAsyncDisposable.DisposeAsync().
GET /sessions/ — Get All Sessions¶
Returns a list of all currently open sessions. Requires elevated privileges.
GET /sessions/allstates — Get All Session States¶
Returns full state information for all active sessions, including open windows and session variables. Requires elevated privileges.
POST /sessions/ping — Keep-Alive¶
Resets the inactivity timer for the current session. Use this to prevent session timeout in long-running integrations.
Recommended pattern: Send a ping every 2–3 minutes for sessions that may sit idle between operations.
// Background keep-alive loop
using var cts = new CancellationTokenSource();
var pingTask = Task.Run(async () =>
{
while (!cts.Token.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromMinutes(2), cts.Token);
await client.PostAsync(
"https://{server}/uiserver0/ui/common/v1/sessions/ping",
new StringContent(string.Empty));
}
}, cts.Token);
GET /sessions/state — Session State¶
Returns the current state of the session, including the active user, company, location, and list of open windows.
Example response:
{
"UserID": "jsmith",
"CompanyID": "01",
"LocationID": 100,
"SessionType": "User",
"OpenWindowCount": 2
}
Session Variables¶
Session variables are key/value pairs scoped to the current session. They persist for the lifetime of the session and can be read/written across API calls.
Read a variable:
Write a variable:
POST /common/v1/sessions/variables/{key}
X-SessionToken: {your-session-token}
Content-Type: application/json
"my-value-here"
Session Preferences¶
Named preferences stored at the session (user) level. Preferences persist across sessions for the same user.
GET /common/v1/sessions/preference/{name}
POST /common/v1/sessions/preference/{name}
PUT /common/v1/sessions/preference/{name}
Window Management¶
List all open windows:
Close windows by menu ID:
Useful for cleaning up open windows before closing a session, or recovering from an error state where windows were left open.
Admin¶
The Admin endpoints provide privileged operations for session and server management. These require the calling session to have P21 administrative permissions.
Admin Endpoints¶
| URI | Method | Operation | Description |
|---|---|---|---|
/admin/serverinfo | GET | GetServerInfo | Retrieve detailed server configuration |
/admin/poolstats | GET | GetPoolStats | Get session pool utilization statistics |
/admin/sessions/{sessionId} | GET | GetSession | Retrieve a specific session by ID |
/admin/sessions/{sessionId} | DELETE | KillSession | Forcibly terminate a specific session |
/admin/windows/{windowId} | DELETE | KillWindow | Forcibly close a specific window |
/admin/taskpool/reset | POST | ResetSessionTaskPool | Reset the session task pool |
GET /admin/serverinfo — Server Information¶
Returns P21 server version, build number, configuration, and deployment details.
GET /admin/poolstats — Pool Statistics¶
Returns session pool utilization, helping diagnose capacity issues.
Example response:
DELETE /admin/sessions/{sessionId} — Kill Session¶
Forcibly terminates a specific session by its ID. Use when a session is stuck or a user cannot close their own session.
Warning
Killing a session immediately terminates any in-progress operation in that session. Unsaved changes will be lost. Use only when necessary.
Alerts¶
GET /alerts/ — Get Alerts¶
Retrieves system alerts and user-level alerts for the current session.
Returns a list of active alerts relevant to the authenticated user, such as overdue tasks, system notifications, or application warnings.
Info¶
GET /info/ — Get Endpoints¶
Returns a list of all service endpoints registered and available on this P21 server instance. This is the primary endpoint discovery mechanism.
No Session Required
The /info/ endpoint does not require an active session. It is useful as a health check and for building dynamic service catalogs.
Use cases:
- Discovering what services are available on a specific P21 installation
- Confirming a service exists before attempting to call it
- Comparing service availability across environments (dev vs. prod)
Server Info¶
GET /serverinfo/ — Get Server Info¶
Returns public server information including P21 version and configuration details. Unlike the admin-level server info, this endpoint is accessible to any authenticated session.
Example response:
{
"Version": "2024.1.0.1234",
"BuildNumber": "1234",
"ServerName": "P21PROD01",
"Environment": "Production"
}
Tasks¶
GET /tasks/ — Get Tasks¶
Retrieves the current user's task list, including overdue tasks, assigned tasks, and pending workflow items.
Example response:
{
"Tasks": [
{
"TaskID": 10045,
"Description": "Approve Purchase Order #88231",
"DueDate": "2024-01-15",
"Priority": "High",
"Overdue": true
}
],
"TotalCount": 1
}
Complete Session Lifecycle Example (C#)¶
public class P21CommonServicesClient : IAsyncDisposable
{
private readonly HttpClient _http;
private readonly string _base;
private string? _token;
public P21CommonServicesClient(string server)
{
_base = $"https://{server}/uiserver0/ui/common/v1";
_http = new HttpClient();
_http.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task LoginAsync(string user, string pass, string workstation)
{
var creds = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{user}:{pass}"));
_http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", creds);
var body = JsonSerializer.Serialize(new
{
SessionType = "User",
WorkstationID = workstation,
PrintMode = "Browser",
SessionTimeout = int.MaxValue
});
var resp = await _http.PostAsync(
$"{_base}/sessions/",
new StringContent(body, Encoding.UTF8, "application/json"));
resp.EnsureSuccessStatusCode();
var data = await resp.Content.ReadFromJsonAsync<JsonElement>();
_token = data.GetProperty("SessionID").GetString()!;
_http.DefaultRequestHeaders.Remove("X-SessionToken");
_http.DefaultRequestHeaders.Add("X-SessionToken", _token);
}
public async Task PingAsync() =>
(await _http.PostAsync($"{_base}/sessions/ping",
new StringContent(string.Empty))).EnsureSuccessStatusCode();
public async Task<string> GetStateAsync()
{
var resp = await _http.GetAsync($"{_base}/sessions/state");
resp.EnsureSuccessStatusCode();
return await resp.Content.ReadAsStringAsync();
}
public async ValueTask DisposeAsync()
{
if (_token is not null)
{
await _http.DeleteAsync($"{_base}/sessions/");
_token = null;
}
_http.Dispose();
}
}