No results

API

Created Jul 26, 2020 by Wim Cools, last modified Nov 24, 2022.Last modified Nov 24, 2022 by Wim Cools.
The Papyrs API allows developers to integrate their own, or other, services and apps with Papyrs. This is a technical document to help developers get started with the API. If you're not a developer but want to integrate Papyrs with existing applications, contact us to see if your application is supported. You can also check out Zapier.com for existing integrations.

If you need the API for any actions which are not covered by this document, or if anything is unclear, let us know

Basics

Conventions

In this document we'll write variables as (#variable). The token value
123456789012 is used as an example, and should be replaced with your API token.

Getting an API token

Go to Site Settings > Integrations & SSO > API to request API access to your account. Once API support is enabled, Site Owners can go to Site Settings > Integrations & SSO and click Generate Token to create a new unique API token for users. Tokens can be revoked again using the Revoke Token.
⚠️ Important: Only share the API token with trusted parties: everyone who has your token can access your account using the API! If you fear your token has leaked to an untrusted party, just use the the Revoke Token link (you can generate a new token afterwards).

Authenticated API calls

  • API call URLs start with https://(#site_url)/(#subsite_url)/api/v1
  • If the API call is on a site-wide endpoint, leave out the subsite-part: https://(#site_url)/api/v1
  • The API is SSL-only
  • Date/time stamps are returned in ISO8601 format in UTC, e.g. 2013-02-06T13:06:23Z
  • Unless specified otherwise, API calls return - and for POST requests, accept - JSON objects
  • The default rate limit is set to 6requests/60seconds, so it's recommended to build in a delay when updating many objects in a loop. If your use case requires a higher rate limit, just let us know.
  • To make API calls with your token, add an X-Auth-Token header to your request.
    For example:

Testing

To quickly test API access and view the JSON response in your browser, you can add the following URL parameters to any /page/... or /pages/ view:
?json&auth_token=123456789012, for example

Example GET request

Example POST request

Example POST request using Python

Error & Status Codes

The following error and status codes are used by the Papyrs API:
Status CodeDescription
200Request successful
400Request formatted incorrectly, e.g. wrong or missing parameter
403You have no permission for this action
404Resource not found, or no permission to access this resource
405Method does not exist (wrong HTTP method, or invalid action)
429Too Many Requests. The default rate limit is 6requests/60seconds. The error field in the response indicates the rate limit used.
500Server error. Something went wrong on our side
Additional error information can be returned in a JSON object containing an
error and status field. For example:

{"error": "You have no permission to access the Feed", "status": 403}

API Endpoints

Pages

The Pages API can be used to get a list of pages, read a page or post a new page. Updating pages is currently only possible by adding individual widgets (see the Widgets endpoint below).

Get a page

GET /api/v1/pages/get/(#page_id)/

Returns: Dictionary with page information. The json field contains the object describing the contents of the page, which is a list of columns, with each column a list of widgets. Each widget is expressed as a dictionary. Example of a page with two columns:

Get all pages

Get a list of all pages in the subsite visible to the user making the request

GET /api/v1/pages/all/

Returns: A list of pages, ordered by creation date (newest page first).

Delete a page

POST /api/v1/pages/delete/(#page_id)/

Returns:

Create a page

POST /api/v1/pages/create/

Requests:
  • The required json field contains the object describing the contents of the page, which is a list of columns, with each column a list of widgets. Each widget is expressed as a dictionary. For examples, see the json values returned by the Get a Page API.
  • title. The title of the new page, required.
  • layout is optional. If omitted, the default layout for the subsite is used.
Returns: the same format as Get a Page.

Copy a page

POST /api/v1/pages/copy/(#page_id)/

Requests:
  • title. The title of the new page, optional.
  • tags. New page tags, optional. Plain string with tags separated by commas.
  • folder_id. Folder for the copy of the page, optional. Can be a folder in a different subsite.
  • path. The path for the copy of the new page, optional. Can point to a different subsite.
Returns:

Records

List all records for a page

GET /api/v1/pages/records/(#page_id)/

Returns: A list of all form records submitted on this page. Each record in the list is described by an object which contains a field and a value field. field contains the name of the record field, and value its value. For example:

Widgets

The Widgets API can be used to get, delete and create individual widgets on a page.

Get a widget

GET /api/v1/page/(#page_id)/paragraph/get/(#widget_id)/

GET /api/v1/page/(#page_id)/heading/get/(#widget_id)/

GET /api/v1/page/(#page_id)/attachment/get/(#widget_id)/
Returns:

Create Text box/Heading

POST /api/v1/page/(#page_id)/paragraph/create/

POST /api/v1/page/(#page_id)/heading/create/
Parameters:

The following additional parameters can be added to the request URL:
WidgetParameterDescriptionDefault
AllformatDescribes the format of
val field in the posted JSON object. Values:

html — The value is HTML and is used unescaped (but sanitized to remove certain tags).

text — The value is Text, any HTML tags are escaped, and line breaks are converted.
html
ParagraphstyleclassDescribes the style of the widget. Values:

"block""quote""note",
"emphasis""thin"

Headingstyleclass
Describes the style of the widget. Values:

"line", "emphasis", "bars", "quote", "boxquote"

HeadingheadingThe size of the heading. h0 is largest, h4 is smallest. Values:

"h0", "h1", "h2", "h3", "h4"

note: the heading size numbering doesn't match the what's used in the user interface

Requests:
Returns: the same as "Get a Widget"

Create widget(s) with Markdown

POST /api/v1/page/(#page_id)/markdown/create/
Requests:
Returns:
If the Markdown code resulted in the creation of one widget, a dictionary describing that widget. If the Markdown code creates multiple widgets, a list of dictionaries describing those widgets. The dictionary has the same format as the result of Create new Text box or Heading widget on a Page above.

Update Text box/Heading

POST /api/v1/page/(#page_id)/paragraph/update/(#widget_id)/

POST /api/v1/page/(#page_id)/heading/update/(#widget_id)/
URL:

(#widget_id) is the ID of the Widget on page (#page_id) you want to update.

The (#widget_id) can be found with the Get a Page request, or from the (#id) field in a Widget request response. Note that when updating a Widget, its (#id) will change. The response will also return a (#version_of_id), which is the original (#id) of the Widget. Passing the (#version_of_id) as the (#widget_id) (instead of the newest ID) is also possible to update the Widget.
Parameters:

The following additional parameters can be added to the request URL:
ParameterDescriptionDefault
formatDescribes the format of
val field in the posted JSON object. Values:

html — The value is HTML and is used unescaped (but sanitized to remove certain tags).

text — The value is Text, any HTML tags are escaped, and line breaks are converted.
html
Requests:
Returns: the same as "Get a Widget"

Create Attachment

POST /api/v1/page/(#page_id)/attachment/create/

Requests:

A file can be uploaded by posting a single file in a field named file, using a multipart/form-data enctype.

Example:

Returns: the same as "Get a Widget"

Updating Attachment

POST /api/v1/page/(#page_id)/attachment/update/(#widget_id)/

URL:

(#widget_id) is the ID of the Widget on page (#page_id) you want to update. The
(#widget_id) can be found with the Get a Page request, or from the (#id) field in a Widget request response. Note that when updating a Widget, its (#id) will change. The response will also return a (#version_of_id), which is the original (#id) of the Widget. Passing the (#version_of_id) as the (#widget_id) (instead of the newest ID) is also possible to update the Widget.

Requests:
Upload the file to be added to the existing Attachment widget by posting it in a field named
file, using a multipart/form-data enctype.

Example:
Returns: the updated Attachment widget, in the same format as "Get a Widget"

Delete a Widget

POST /api/v1/page/(#page_id)/paragraph/delete/(#widget_id)/

POST /api/v1/page/(#page_id)/heading/delete/(#widget_id)/

POST /api/v1/page/(#page_id)/attachment/delete/(#widget_id)/

Returns:

Search

The Search API can be used to query Papyrs' built-in search engine and find intranet pages, comments, form entries, people or files. The results returned through the API are the same as if the API user would have typed in the query in Papyrs' search box.

Search query

Get a list of search results based on a query.

GET /api/v1/search/query/

Parameters:

The following additional parameters need to be added to the request URL:
ParameterDescription
qThe search query

Example: /api/v1/search/query/?q=test
Returns:

A list of search results in the results field. Each result is described by a dictionary with fields as in the example below. cat specifies the type of result, which can be one of the following:
Cat valueDescription
PageResult is a page
FileResult is a file
ContactResult is a person from the People Directory
FormResult is a form entry
CommentResult is a comment

People

The People API can be used to get a list of people - and their details - in your account, as shown in the People Directory.

Get all people

Get a list of all people in your site (as shown in the People Directory). Guest users, invited to individual pages, are not included. The API user must have access to the People Directory, or a 403 Forbidden is returned. This API call can be made for a specific subsite (by including it in the API URL), or on the site URL to get a list of all users on the site.

GET /api/v1/people/all/

Returns: A list of people, ordered by join date (newest user first).
If waiting_invite is true, the user has been invited but has not accepted their invitation yet. Attributes like dates are shown in the user's own locale.

Delete a user

Permanently delete a user from your site, including all subsites. Site Owners only.

POST /api/v1/people/delete/(#user_id)/

Returns:

Invite a new user to the site

Add a user to the site by email address. The request must be made on the site-wide URL (i.e. without a /@subsite/ part in the API URL).

Users invited to the site receive a welcome email with information on how they can log in (optional). If you're using any SSO methods such as SAML or Google Workspace, the user will be able to log in through those methods.

POST /api/v1/people/invite/
Requests:
A JSON object with the following parameters: email_address, name, auto_join, skip_welcome_email. email_address is a required field containing the email address of the new user to be invited, name is an optional field with their name (when not specified, the email address is also used as name).

auto_join is an optional value, true or false (default: true), indicating whether the new user should be automatically added to all Auto-join Subsites, see Site Settings > Site > Auto-join Subsites. When set to false, the user is added to the site, but won't be member of any subsite initially. See the Add a user to a subsite request below to add users later on.

skip_welcome_email is an optional value, true or false (default: false). When true the user won't receive an email about being invited to the site. The welcome email contains a secure token the new user needs to set their password, so only disable welcome emails when users have an alternative method of singing in.
Example:
Returns:
A JSON object with success set to true if the request was successful (otherwise the value is false, with an error message in error). On success, the JSON contains details about the new user like their id and email address. The JSON object also contains a list of the new user's subsite membership with permission and notification levels.

Add a user to a subsite

Add a User (who already exists on your site) to a specific subsite. The user_id of a User can be found using the Get all people request above.

POST /api/v1/people/add_to_subsite/(#user_id)/

Admins who are member of a subsite can call this endpoint on an API URL which includes the subsite, i.e. /@mysubsite/api/v1/people/add_to_subsite/(#user_id)/, to add people to that specific subsite. 

Site Owners can call the endpoint on the site-wide URL, i.e. /api/v1/people/add_to_subsite/(#user_id)/, and provide a subsite_id parameter in the request JSON (see below). This way, Site Owners can also invite themselves to any subsite.
Requests:
A JSON object with two optional parameters: skip_welcome_email and role. When skip_welcome_email is true (default: false), the user won't receive an email about being added to the subsite. role needs to be either viewer, editor or admin. When no role is given, the subsite's default is used (see Site Settings > Subsite > Default permissions). 

When calling the endpoint on the site-wide API URL (only Site Owners can do this), the JSON object must include a subsite_id parameter, with the ID of the subsite the user should be added to (see the Get all subsites endpoint to find the ID of a subsite). When calling the endpoint on a subsite-specific API URL, the subsite_id parameter must not be included.

For example:
Examples:
Returns:
A JSON object with success set to true if the request was successful (otherwise the value is false, with an error message in error). On success, the JSON contains details about the user like their id and email address. When the authenticated API user is a Site Owner, the JSON object also contains an updated list of the user's (with user_id) current subsite membership with permission and notification levels.

Delete a user from a subsite

Delete a User (who already exists on your site and is member of a subsite) from a specific subsite (the API URL must include the subsite). The user_id of a User can be found using the Get all people request above.

POST /api/v1/people/remove_from_subsite/(#user_id)/
Example:
Returns:

The returned value is similar to Add a user to a subsite, see above.

Set permission of a user on a subsite

Set the permission of a User in a specific subsite (the API URL must include the subsite). The user_id of a User can be found using the Get all people request above.

POST /api/v1/people/set_permission/(#user_id)/
Requests:
A JSON object with one required attribute: role , which needs to be either admin, editor or viewer.
Returns:

The returned value is similar to Add a user to a subsite, see above.

Set notifications of a user on a subsite

Set the notification level of a User in a specific subsite (the API URL must include the subsite). The user_id of a User can be found using the Get all people request above.

POST /api/v1/people/set_notifications/(#user_id)/
Requests:

A JSON object with one required attribute: notifications, which needs to be either off, on or digest.
Returns:

The returned value is similar to Add a user to a subsite, see above.

Folders

Get all folders

GET /api/v1/folder/tree/

You can use the API to retrieve the folder tree on a subsite. Returns a list of all folders on the subsite with their id and path.

Returns:

Delete a folder

POST /api/v1/folder/delete/

You can use the API to delete a folder (along with any empty subfolders).

Requests:

A JSON object with either a folder_id or a path (but not both). The Main folder isn't included in the path, and you cannot delete the main folder of a subsite.
Returns:

Copy a folder

POST /api/v1/folder/copy/

You can use the API to copy a folder (with all pages and all subfolders). You have to provide a source and a destination. The destination can be a folder in a different subsite, provided the API user is an Editor or Admin in both subsites.

Requests:

A JSON object with copy_folder_id or copy_path and
target_folder_id or target_path. For example
Returns:
If there are many pages to copy you may need to call the copy API multiple times with a JSON object returned in more. When all pages have been copied more will be false.

Discussions

Post to a Discussion

POST /api/v1/feed/post/(#page_id)/

You can use the API to post a comment to any page with a Discussion widget.

Requests:
Returns:

Subsites

Get all subsites

Get a list of all subsites in a site (Site Owners only). This is a site-wide API request, so use the site's URL as the API's base URL.

POST /api/v1/subsites/all/

Returns:

Create a subsite

Create a new subsite on the site. Just like creating a subsite through the user interface, the new subsite starts out empty, only containing the API user who created it in this case.

This is a site-wide API request, so use the site's URL as the API's base URL.
POST /api/v1/subsites/create/
Requests:
A JSON object with two parameters: title and description (description is optional). For example:
Returns:
Details of the new subsite, for example: