Getting started with PI Web API

Blog Post created by pthivierge on Apr 17, 2015

Edit 2017-12-11:


Introduction and available resources

This post will give you basic knowledge about PI Web API and the Web's world.  This is a quick starter to master the basic concepts.

However you will also be interested by the following resources:




Getting Started with PI Web API - The post


I was asked lately to provide an example that shows how to create an event frame with PI Web API.  This was my first time I had to work with the PI Web API and I thought it would be useful it to share my experience in this blog post.


Things you absolutely need to know and be familiar with

I will first start by the list of things that I think you need to know before you dive in the subject:

  • PI Web API is "like" a web site, you interact with it by using urls.  Ex:  Each data query you need to do against PI Web API will be a different url.
  • Depending on the PI Web API query you need to do, you will either need to do an HTTP Request of type GET, POST, DELETE or PATCH.
  • Every HTTP Request has a header. The header will be different weather you are performing a POST, a GET Request, etc...
    • Requests have a method: GET/POST
    • a Host i.e. PI Web API Server,
    • And other possible parameters that we will cover as needed.


Example - GET request SENT to the server that hosts PI WEB API

GET /piwebapi/system/userinfo HTTP/1.1
Host: tst-srv-pi2015
Connection: keep-alive
Cache-Control: max-age=0
Accept: */*
Origin: http://localhost:63342
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36
Referer: http://localhost:63342/JavascriptFramework/JavascriptFramework/src/index.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4


  • The client you will use ( Browser + JavaScript, c#, Postman Google Add In) will have a HUGE impact on CORS, if you don't understand CORS you absolutely need to stop here and take 5-10 minutes to understand it. Mozilla Foundation gives a great explanation.  Please keep it in mind and make sure you understand when it applies.  Wikipedia article is not bad neither.  But to be simple if your application is not built to run in a web browser you should not care to much about CORS.


I am doing a little summary here in case you don't look


What is CORS ? - read this if you are going to request data with JavaScript (ajax / XMLHTTPRequest)

I'll give my little quick and dirty explanation of the thing, this is not my field of expertise so it may not be as accurate as the articles presented above:


At the very first there is the Cross-site HTTP requests limitation.  This is implemented in the latest browsers and prevents JavaScript code to execute (ajax) queries to an external website (domain).

ex: a script that is inside the web page could not (without proper CORS settings on the remote site) request data on  This was implemented for security reasons.

Then the W3C group has worked on a recommendation to see how resources can be shared between different domains, and they came up with CORS. It stands for Cross-Origin Resource sharing.

CORS is a way to configure the "foreign" web server to accept Cross-site HTTP requests from the client, the client exposes the website origin to the foreign server with its header.


There are two types of HTTP requests that can occur with CORS - Reference here


Simple Requests

  • Only uses GET, HEAD or POST. If POST is used to send data to the server, the Content-Type of the data sent to the server with the HTTP POST request is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain.
  • Does not set custom headers with the HTTP Request (such as X-Modified, etc.)


Preflighted Requests

  • It uses methods other than GET, HEAD or POST.  Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
  • It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)

Preflighted requests will first send an OPTION HTTP request, to get details on what is allowed to send to the "foreign" (PI Web API) server.  This is where the PI WEB API Server will send us back : "CorsHeaders": "accept, content-type, Access-Control-Allow-Origin" for our Ajax query to work!


Ok! so if we have something to remember here it is:

  • If I am create a web client using JavaScript and a browser, I need to make sure I understand CORS.  GET may work easily and POST will be pre-flighted.
  • If I am using other technologies (.net, python, etc) this is less of a problem


Enough with CORS!


How to work with PI Web API?


You will need the documentation, it covers installation, configuration debugging and more...


When you navigate to you PI Web Api Server using your browser, you will be performing GET queries, browser do not execute other types of HTTP requests such as POST unless there is a form and a button on the page, or there is javascript that does that for you. This means you cannot do any type of actions from your browser by simply clicking.


This is the very first approach you should have, so from https://YOUR_SERVER/piwebapi you can find links that will lead you to

This is the starting point, you have to get in one of these links and select a server, from within the server scope, you can then call the data you need.


Ex: I want to Element Attribute values?

I select the AssetServer, then I select "Databases" and it returns me the list of all AF Databases and their possible "actions", once you get there you can go further down and you will see at some point the values you are interested with...

You can also look at the documentation (/piwebapi/help ) to see how to use different methods:

"Links": {
  "Self": "https://tst-srv-pi2015/piwebapi/assetdatabases/D0gaIE9drlp06O5SHUQQ87kgLQVMmlQYQ0q0cOOuZUedhgVFNULVNSVi1QSTIwMTRcU1VQUE9SVA",
  "Elements": "https://tst-srv-pi2015/piwebapi/assetdatabases/D0gaIE9drlp06O5SHUQQ87kgLQVMmlQYQ0q0cOOuZUedhgVFNULVNSVi1QSTIwMTRcU1VQUE9SVA/elements",
  "ElementTemplates": "https://tst-srv-pi2015/piwebapi/assetdatabases/D0gaIE9drlp06O5SHUQQ87kgLQVMmlQYQ0q0cOOuZUedhgVFNULVNSVi1QSTIwMTRcU1VQUE9SVA/elementtemplates",
  "EventFrames": "https://tst-srv-pi2015/piwebapi/assetdatabases/D0gaIE9drlp06O5SHUQQ87kgLQVMmlQYQ0q0cOOuZUedhgVFNULVNSVi1QSTIwMTRcU1VQUE9SVA/eventframes",
  "AssetServer": "https://tst-srv-pi2015/piwebapi/assetservers/S0gaIE9drlp06O5SHUQQ87kgVFNULVNSVi1QSTIwMTQ",
  "ElementCategories": "https://tst-srv-pi2015/piwebapi/assetdatabases/D0gaIE9drlp06O5SHUQQ87kgLQVMmlQYQ0q0cOOuZUedhgVFNULVNSVi1QSTIwMTRcU1VQUE9SVA/elementcategories",
  "AttributeCategories": "https://tst-srv-pi2015/piwebapi/assetdatabases/D0gaIE9drlp06O5SHUQQ87kgLQVMmlQYQ0q0cOOuZUedhgVFNULVNSVi1QSTIwMTRcU1VQUE9SVA/attributecategories",
  "TableCategories": "https://tst-srv-pi2015/piwebapi/assetdatabases/D0gaIE9drlp06O5SHUQQ87kgLQVMmlQYQ0q0cOOuZUedhgVFNULVNSVi1QSTIwMTRcU1VQUE9SVA/tablecategories",
  "EnumerationSets": "https://tst-srv-pi2015/piwebapi/assetdatabases/D0gaIE9drlp06O5SHUQQ87kgLQVMmlQYQ0q0cOOuZUedhgVFNULVNSVi1QSTIwMTRcU1VQUE9SVA/enumerationsets",
  "Tables": "https://tst-srv-pi2015/piwebapi/assetdatabases/D0gaIE9drlp06O5SHUQQ87kgLQVMmlQYQ0q0cOOuZUedhgVFNULVNSVi1QSTIwMTRcU1VQUE9SVA/tables"


You will see that the documentation talks a lot about Web IDs, if you are building your own application, it would be a clever approach to Cache them on the client, so you can re-use them and avoid to perform so many queries on the PI WEB API Server.

This way you can do data calls directly.


How do I test other type of HTTP requests then?

You should use Postman REST client to do that, it is an add in for chrome.


Here is an example that shows how to use it for post request: you must notice the Content-Type header that is required.


This is the result "201 created" after the Ssend button was pressed.




Make PI WEB API ready for ajax calls - This is The Configuration I used for my development environment - DO NO USE RED PARAMETERS FOR A PRODUCTION SERVER THAT IS EXPOSED TO THE INTERNET!


You can simply use PI System Explorer to configure that, this is in the Configuration Database: \\YOUR_AFSERVER\Configuration\OSIsoft\PI Web API\YOUR_PI_WEB_API_SERVER\System Configuration.

Here are the settings you need to have to use jquery + ajax with CORS, please take these settings as for development purpose only.  In production I would change red settings to tighten the security at the maximum I can.

  "AuthenticationMethods": [



  "CorsHeaders": "accept, content-type, Access-Control-Allow-Origin",

  "CorsMethods": "*",

  "CorsOrigins": "*",

  "CorsSupportsCredentials": false,




I told you that I was looking to create an event frame out of this right? Here is my little example.

A little bonus, it displays the user information too.

This little app does POST and GET HTTP requests and there is also a .js file that wraps content related to PI WEB API


To make it work you will need to change one line in the file app-pi_web_api.js line 12, you need to replace the server name for yours.

var piwebapiBaseUrl = "https://tst-srv-pi2015/piwebapi/";



The code is definitely not perfect, but as I am studying for the MS Exam 70-480 - Programming in HTML5 with JavaScript and CSS3 at the moment, I am trying to put things as right as I can.

( you can see from the screenshot below that I did not work the CSS3 part very hard )



2015-04-17_17-22-07_PI Web API Example.png

This is just the beginning for this example, I am planning to add more features such as tag search, and get data as I get "howto's" requests!



Other useful resources:



Hope this helps!