User and Group Management API

👤 This documentation is intended for Site Administrators.

Table of Contents:

<UL>
<LI>The <a href="#UMAPI">User Management API</a> allows clients to fetch, create, update and delete users with their group associations in a per site basis through a RESTful API. The User Management API includes:</LI>
<UL>
<LI><a href="#GetUsers">GET Users</a></LI>
<LI><a href="#GetSingleUser">GET Single User</a></LI>
<LI><a href="#CreateUser">CREATE User</a></LI>
<LI><a href="#UpdateUser">UPDATE User</a></LI>
<LI><a href="#DeleteUser">DELETE User</a></LI>
</UL>
<LI>The <a href="#GMAPI">Group Management API</a> similarly allows clients to fetch, create, update and delete groups. The Groups Management API includes:</LI>
<UL>
<LI><a href="#GetGroups">GET Groups</a></LI>
<LI><a href="#GetSingleGroup">GET Single Group</a></LI>
<LI><a href="#CreateGroup">CREATE Group</a></LI>
<LI><a href="#UpdateGroup">UPDATE Group</a></LI>
<LI><a href="#DeleteGroup">DELETE Group</a></LI>
</UL>
<LI><a href="#LookingForMore">Looking For More?</a></LI>
</UL>

Note: User and Group Management API is available on select plans. Site administrators can contact their Customer Success Manager for additional information.

<HR>

<a name="UMAPI"></a>

User Management API

Find the site's hostname and API key. The site's hostname can be found in any dashboard URL. The API key can be found in the Billing and Authentication tab of the gear menu in the lower left-hand corner of Periscope.

The API Key is unique to each site. Avoid exposing this API Key by storing them as environment variables. If an API Key has been accidentally revealed, please reach out to support@periscopedata.com or the in-app live chat to get the API Key rotated.

To successfully authenticate against the API:

Base URL: https://app.periscopedata.com

Authentication: Http-X-Partner-Auth: <Site-Host:API-KEY>

For example: For a site with dashboard URLs that look like 'https://app.periscopedata.com/app/example_site/' and a sample API key of 'e179017a-62b0-4996-8a38-e91aa9f1'. The <Site-Host:API-KEY> would be <example_site:e179017a-62b0-4996-8a38-e91aa9f1>

The User Management API needs to be enabled on a given site for the endpoints to work. Otherwise, it will provide a 404 response.

<a href="#top">Back to top</a>

<a name="GetUsers"></a>

GET Users

<div><table>
<thead>
<tr>
<th style="width:200px;text-align:left">URL</th>
<th style="width:200px;text-align:left">Parameters</th>
<th style="width:300px;text-align:left">HTTP VERB</th>
<th style="width:300px;text-align:left">Response Codes</th>
</tr>
</thead>
<tbody>
<tr>
<td>/api/v1/users</td>
<td>next_page_start=<string> (Optional)</td>
<td>GET</td>
<td>200 if user records are successfully returned<br><br>403 Forbidden if Http-X-Partner-Auth header not specified or API_KEY is incorrect or Site-Host does NOT exist</td>
</tr>
</tbody>
</table></div>

Response Body

<div><table>
<thead>
<tr>
<th style="width:300px;text-align:left">Response Body</th>
<th style="width:200px;text-align:left">Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>{<br>
   "total_users": integer,<br>
   "users_this_page": integer,<br>
   "next_page_start": string,<br>
   "users": [<br>
       {<br>
           "first_name": string,<br>
           "last_name": string,<br>
           "email": string,<br>
           "groups": [<br>
               string<br>
           ],<br>
           "last_login_at": string (ISO date),<br>
           "password_updated_at":  string (ISO date),<br>
           "tfa_enabled": boolean<br>
      }....<br>
   ]<br>
}
</td>
<td>The API only returns 100 records If there are more than 100 users, the API returns an email_address in next_page_start and the clients make a call to ?next_page_start=<email_address> to fetch the next 100 records and so on</td>
</tr>
</tbody>
</table></div>

<a href="#top">Back to top</a>

<a name="GetSingleUser"></a>

GET Single User

<div><table>
<thead>
<tr>
<th style="width:200px;text-align:left">URL</th>
<th style="width:200px;text-align:left">HTTP Headers</th>
<th style="width:300px;text-align:left">HTTP VERB</th>
<th style="width:300px;text-align:left">Response Codes</th>
</tr>
</thead>
<tbody>
<tr>
<td>/api/v1/users</td>
<td><b>REQUIRED HTTP HEADER:</b><br>
HTTP-X-EMAIL: &lt;EMAIL_ADDRESS &gt;</td>
<td>GET</td>
<td>200 if user record is successfully returned<br>
<br>
403 Forbidden if Http-X-Partner-Auth header not specified or API_KEY is incorrect or Site-Host does NOT exist<br>
<br>
400 if the email_address does NOT belong to the user on this site
</td>
</tr>
</tbody>
</table></div>

Response Body

<div><table>
<tbody>
<tr>
<td> {<br>
           "first_name": string ,<br>
           "last_name": string,<br>
           "email": string,<br>
           "groups": [<br>
               string<br>
           ],<br>
           "last_login_at": string (ISO date),<br>
           "password_updated_at":  string (ISO date),<br>
           "tfa_enabled": boolean<br>
}
</td>
</tr>
</tbody>
</table></div>

<a href="#top">Back to top</a>

<a name="CreateUser"></a>

CREATE User

<div><table>
<thead>
<tr>
<th style="width:200px;text-align:left">URL</th>
<th style="width:200px;text-align:left">Parameters/HTTP Header</th>
<th style="width:300px;text-align:left">HTTP VERB</th>
<th style="width:300px;text-align:left">Response Codes</th>
</tr>
</thead>
<tbody>
<tr>
<td>/api/v1/users</td>
<td><b>OPTIONAL PARAMETER</b><br>
?test_mode=true <br>
<br>
If this parameter is set, then ONLY VALIDATIONS run and the actual user does NOT get created
</td>
<td>POST</td>
<td>201 if user record is successfully returned<br>
<br>
403 Forbidden if Http-X-Partner-Auth header not specified or API_KEY is incorrect or Site-Host does NOT exist<br>
<br>
400 if the required fields are NOT specified or if they are invalid (first_name, last_name, email, invited_by_email)<br>
<br>
409 if the email_address already exists
</td>
</tr>
</tbody>
</table></div>

Request Body

<div><table>
<tbody>
<tr>
<td> {<br>
           "first_name": string ,<br>
           "last_name": string,<br>
           "email": string,<br>
           "groups": [<br>
               string <br>
           ],<br>
           "invited_by_email": string
}
</td>
</tr>
</tbody>
</table></div>

Response Body

<div><table>
<tbody>
<tr>
<td> {<br>
           "first_name": string ,<br>
           "last_name": string,<br>
           "email": string,<br>
           "groups": [<br>
               string<br>
           ],<br>
           "Last_login_at": string (ISO date),<br>
           "password_updated_at":  string (ISO date),<br>
           "tfa_enabled": boolean<br>
}<br>
<br>
If test_mode=true is specified, the response is -
{"message":"Action would have completed successfully"}
</td>
</tr>
</tbody>
</table></div>

<a href="#top">Back to top</a>

<a name="UpdateUser"></a>

UPDATE User

<div><table>
<thead>
<tr>
<th style="width:200px;text-align:left">URL</th>
<th style="width:200px;text-align:left">Parameters</th>
<th style="width:300px;text-align:left">HTTP VERB</th>
<th style="width:300px;text-align:left">Response Codes</th>
</tr>
</thead>
<tbody>
<tr>
<td>/api/v1/users</td>
<td><b>REQUIRED HTTP HEADER:</b><br>
HTTP-X-EMAIL: &lt;EMAIL_ADDRESS &gt;<br>
<br>
<b>OPTIONAL PARAMETER:</b><br>
?test_mode=true<br>
<br>
If this parameter is set, then ONLY VALIDATIONS run and the actual user does NOT get updated
</td>
<td>PUT</td>
<td>200 if operation is successful<br>
<br>
403 Forbidden if Http-X-Partner-Auth header not specified or API_KEY is incorrect or Site-Host does NOT exist<br>
<br>
400 if the the user does NOT exist for the site
</td>
</tr>
</tbody>
</table></div>

Request Body

<div><table>
<tbody>
<tr>
<td>Any permutation of the following fields is acceptable<br>
<br>
{<br>
           "first_name": string ,<br>
           "last_name": string,<br>
           "groups": [<br>
               string <br>
           ]<br>
}
</td></tr>
<tr><td>
Some examples:<br>
1) PUT {"first_name": "..."} updates only first_name since no groups is passed in.<br>
2) PUT {"first_name": "...", groups:[]} updates first_name and set groups to ["All Users"]<br>
3) PUT {"first_name": "...", groups:["All Users"]} same behavior as (2)<br>
</td>
</tr>
</tbody>
</table></div>

Response Body

<div><table>
<tbody>
<tr>
<td>{<br>
           "first_name": string ,<br>
           "last_name": string,<br>
           "email": string,<br>
           "groups": [<br>
               string<br>
           ],<br>
           "last_login_at": string (ISO date),<br>
           "password_updated_at":  string (ISO date),<br>
           "tfa_enabled": boolean<br>
}<br>
<br>
If test_mode=true is specified, the response is -
{"message":"Action would have completed successfully"} <br>
</td>
</tr>
</tbody>
</table></div>

<a href="#top">Back to top</a>

<a name="DeleteUser"></a>

DELETE User

Currently, when you delete a user, the deleter gains ownership over all the objects owned by deleted user.

<div><table>
<thead>
<tr>
<th style="width:200px;text-align:left">URL</th>
<th style="width:200px;text-align:left">Parameters</th>
<th style="width:300px;text-align:left">HTTP VERB</th>
<th style="width:300px;text-align:left">Response Codes</th>
</tr>
</thead>
<tbody>
<tr>
<td>/api/v1/users</td>
<td><b>REQUIRED HTTP HEADER:</b><br>
HTTP-X-EMAIL: &lt;EMAIL_ADDRESS&gt;<br>
<br>
<b>OPTIONAL PARAMETER</b><br>
?test_mode=true<br>
<br>
If this parameter is set, then ONLY VALIDATIONS run and the actual user does NOT get deleted
</td>
<td>DELETE
</td>
<td>200 if operation is successful<br>
<br>
403 Forbidden if Http-X-Partner-Auth header not specified or API_KEY is incorrect or Site-Host does NOT exist<br>
<br>
400 if the the user does NOT exist for the site
</td>
</tr>
</tbody>
</table></div>

<a href="#top">Back to top</a>

<HR>

<a name="GMAPI"></a>

Group Management API

Find the site's hostname and API key. The site's hostname can be found in any dashboard URL. The API key can be found in the Billing and Authentication tab of the gear menu in the lower left-hand corner of Periscope.

The API Key is unique to each site. Avoid exposing this API Key by storing them as environment variables. If an API Key has been accidentally revealed, please reach out to support@periscopedata.com or the in-app live chat to get the API Key rotated.

To successfully authenticate against the API:

Base URL: https://app.periscopedata.com

Authentication: Http-X-Partner-Auth: <Site-Host:API-KEY>

For example: For a site with dashboard URLs that look like 'https://app.periscopedata.com/app/example_site/' and a sample API key of 'e179017a-62b0-4996-8a38-e91aa9f1'. The <Site-Host:API-KEY> would be <example_site:e179017a-62b0-4996-8a38-e91aa9f1>

The Group Management API needs to be enabled on a given site for the endpoints to work. Otherwise, it will provide a 404 response.

<a href="#top">Back to top</a>

<a name="GetGroups"></a>

GET Groups

<div><table>
<thead>
<tr>
<th style="width:200px;text-align:left">URL</th>
<th style="width:200px;text-align:left">Parameters</th>
<th style="width:300px;text-align:left">HTTP VERB</th>
<th style="width:300px;text-align:left">Response Codes</th>
</tr>
</thead>
<tbody>
<tr>
<td>/api/v1/groups</td>
<td>next_page_start=<string> (Optional)</td>
<td>GET</td>
<td>200 if group records are successfully returned<br><br>403 Forbidden if Http-X-Partner-Auth header not specified or API_KEY is incorrect or Site-Host does NOT exist</td>
</tr>
</tbody>
</table></div>

Response Body

<div><table>
<thead>
<tr>
<th style="width:300px;text-align:left">Response Body</th>
<th style="width:200px;text-align:left">Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>{<br>
   "total_groups": integer,<br>
   "groups_this_page": integer,<br>
   "next_page_start": string,<br>
   "groups": [<br>
       {<br>
           "name": string ,<br>
           "access": string (sql, discovery, view)<br>
      }<br>
   ]<br>
}</td>
<td>The API only returns 100 records If there are more than 100 groups, the API returns a group_name in next_page_start and the clients make a call to ?next_page_start=<group_name> to fetch the next 100 records and so on</td>
</tr>
</tbody>
</table></div>

<a href="#top">Back to top</a>

<a name="GetSingleGroup"></a>

GET Single Group

<div><table>
<thead>
<tr>
<th style="width:200px;text-align:left">URL</th>
<th style="width:200px;text-align:left">HTTP Headers</th>
<th style="width:300px;text-align:left">HTTP VERB</th>
<th style="width:300px;text-align:left">Response Codes</th>
</tr>
</thead>
<tbody>
<tr>
<td>/api/v1/groups/{group_name}</td>
<td></td>
<td>GET</td>
<td>200 if group_name record is successfully returned<br>
<br>
403 Forbidden if Http-X-Partner-Auth header not specified or API_KEY is incorrect or Site-Host does NOT exist<br>
<br>
404 if the group_name does NOT exist on this site
</td>
</tr>
</tbody>
</table></div>

Response Body

<div><table>
<tbody>
<tr>
<td> {<br>
           "name": string ,<br>
           "access": string (sql, discovery, view),<br>
           "dashboards" : [ {“name”: “Test Dashboard”, “access”: “Edit”}, {“name”: “Untitled Dashboard”, “access”: “Edit”}...]<br>
  }
</td>
</tr>
</tbody>
</table></div>

<a name="CreateGroup"></a>

CREATE Group

<div><table>
<thead>
<tr>
<th style="width:200px;text-align:left">URL</th>
<th style="width:200px;text-align:left">Parameters/HTTP Header</th>
<th style="width:300px;text-align:left">HTTP VERB</th>
<th style="width:300px;text-align:left">Response Codes</th>
</tr>
</thead>
<tbody>
<tr>
<td>/api/v1/groups/</td>
<td><b>OPTIONAL PARAMETER</b><br>
?test_mode=true <br>
<br>
If this parameter is set, then ONLY VALIDATIONS run and the actual group does NOT get created
</td>
<td>POST</td>
<td>201 if group record is successfully returned<br>
<br>
403 Forbidden if Http-X-Partner-Auth header not specified or API_KEY is incorrect or Site-Host does NOT exist<br>
<br>
400 if the required fields are NOT specified or if they are invalid (name and access)<br>
<br>
400 if the access is NOT one of sql/discovery/view<br>
<br>
409 if the group already exists
</td>
</tr>
</tbody>
</table></div>

Request Body

<div><table>
<tbody>
<tr>
<td> {<br>
           "name": string ,<br>
           "access": string (“sql/discovery/view”),<br>
           "created_by_email": string (“email_address”)<br>
}
</td>
</tr>
</tbody>
</table></div>

Response Body

<div><table>
<tbody>
<tr>
<td> {<br>
           "name": string ,<br>
           "access": string (“sql/discovery/view”),<br>
           "created_by_email": string (“email_address”)<br>
}<br>
<br>
If test_mode=true is specified, the response is -
{"message":"Action would have completed successfully"}
</td>
</tr>
</tbody>
</table></div>

Note: The backend logic will "view/sql/discovery" and perform the following mapping in the group_role table

Group_role table mapping:

<div><table>
<thead>
<tr>
<td><b>Access</b></td>
<td><b>can_edit column</b></td>
<td><b>can_drag_and_drop column</b></td>
</tr>
</thead>
<tbody>
<tr>
<td>View</td>
<td>false</td>
<td>false</td>
</tr>
<tr>
<td>SQL</td>
<td>true</td>
<td>false</td>
</tr>
<tr>
<td>Discovery</td>
<td>false</td>
<td>true</td>
</tr>
</tbody>
</table></div>

<a href="#top">Back to top</a>

<a name="UpdateGroup"></a>

UPDATE Group

<div><table>
<thead>
<tr>
<th style="width:200px;text-align:left">URL</th>
<th style="width:200px;text-align:left">Parameters</th>
<th style="width:300px;text-align:left">HTTP VERB</th>
<th style="width:300px;text-align:left">Response Codes</th>
</tr>
</thead>
<tbody>
<tr>
<td>/api/v1/groups/{group_name}</td>
<td><b>OPTIONAL PARAMETER:</b><br>
?test_mode=true <br>
<br>
If this parameter is set, then ONLY VALIDATIONS run and the actual group does NOT get updated
</td>
<td>PUT</td>
<td>200 if operation is successful<br>
<br>
403 Forbidden if Http-X-Partner-Auth header not specified or API_KEY is incorrect or Site-Host does NOT exist<br>
<br>
400 if the access is NOT one of sql/discovery/view
</td>
</tr>
</tbody>
</table></div>

Request Body

<div><table>
<tbody>
<tr>
<td>Any permutation of the following fields is acceptable<br>
<br>
{<br>
           "first_name": string ,<br>
           "last_name": string,<br>
           "groups": [<br>
               string <br>
           ]<br>
}
</td></tr>
<tr><td>
Some examples:<br>
1) PUT {"name": "..."} updates only name<br>
2) PUT {"access": “”} updates only access<br>
3) PUT {"name": "...", “access”: “”} updates both name and access
</td>
</tr>
</tbody>
</table></div>

Response Body

<div><table>
<tbody>
<tr>
<td>{<br>
           "name": string ,<br>
           "access": string (“sql/discovery/view”) <br>
}<br>
<br>
If test_mode=true is specified, the response is -
{"message":"Action would have completed successfully"}
</td>
</tr>
</tbody>
</table></div>

<a href="#top">Back to top</a>

<a name="DeleteGroup"></a>

DELETE Group

<div><table>
<thead>
<tr>
<th style="width:200px;text-align:left">URL</th>
<th style="width:200px;text-align:left">Parameters</th>
<th style="width:300px;text-align:left">HTTP VERB</th>
<th style="width:300px;text-align:left">Response Codes</th>
</tr>
</thead>
<tbody>
<tr>
<td>/api/v1/groups/{group_name}</td>
<td><b>OPTIONAL PARAMETER</b><br>
?test_mode=true<br>
<br>
If this parameter is set, then ONLY VALIDATIONS run and the actual group does NOT get deleted
</td>
<td>DELETE
</td>
<td>200 if operation is successful<br>
<br>
403 Forbidden if Http-X-Partner-Auth header not specified or API_KEY is incorrect or Site-Host does NOT exist<br>
<br>
404 if group does NOT EXIST
</td>
</tr>
</tbody>
</table></div>

<a href="#top">Back to top</a>

<a name="LookingForMore"></a>

Looking for More?

Refer to our community for examples on implementing the above API calls

<a href="#top">Back to top</a>

Our support team is ready to help