Introduction
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.
Basics
Note that the API, and therefore this document, is still in active development as we add more endpoints and functionality. If you need the API for any actions which are not covered by this document, or if anything is unclear, let us know!
ConventionsIn 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.
Go to Site Settings > Integrations & SSO > API to request API access to your account. Once API support is enabled, Administrators 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).
- All API call URLs start with
https://(#group_name).papyrs.com/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
- To make API calls with your token, simply add an auth_token field to your request URL. For example,
https://example.papyrs.com/api/v1/pages/all/?auth_token=123456789012
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
https://example.papyrs.com/pages/alphabetical/?json&auth_token=123456789012
curl -H "Content-Type: application/json" \ -H "User-Agent: MyApp" \ https://example.papyrs.com/api/v1/pages/all/?auth_token=123456789012Example POST request:
curl -H "Content-Type: application/json" \ -H "User-Agent: MyApp" \ -d '{"widget": {"val": "Hello <b>World</b>!"}}' \ https://example.papyrs.com/api/v1/page/SKTL/paragraph/create/?auth_token=123456789012\&format=htmlExample POST request using Python:
import requests url = "https://example.papyrs.com/api/v1/feed/post/?auth_token=111222333444" r = requests.post(url, json={'msg': 'hello from python!'}) if r.status_code == 200: print "OK!" else: print r.status_code, r.reason, r.textError & Status Codes
The following error and status codes are used by the Papyrs API:
Status Code | Description |
---|---|
200 | Request successful |
400 | Request formatted incorrectly, e.g. wrong or missing parameter |
403 | You have no permission for this action |
404 | Resource not found, or no permission to access this resource |
405 | Method does not exist (wrong HTTP method, or invalid action) |
429 | Too Many Requests. The default rate limit is 6requests/60seconds. The error field in the response indicates the rate limit used. |
500 | Server 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 PageGET /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:
{ "category": "Test Folder/Sub Folder", "created_at": "2013-02-06T13:06:23Z", "created_by": "Wim", "id": "SKvP", "is_public": false, "json": [ [ { "classname": "Heading", "html": "Welcome!", "text": "Welcome!", "id": "SQRs", }, { "classname": "Paragraph", "html": "This is some example test, this is <b>bold</b>!", "id": "SQRc", "text": "This is some example test, this is bold!" } ], [ { "classname": "Paragraph", "html": "Text box in second column.", "id": "SQRV", "text": "Text box in second column." } ] ], "layout": [ [ [ 8, 1 ], [ 4, 1 ] ] ], "notifications": { "SXZb": "off", "SXZr": "on", "SxBt": "on", "SxBZ": "on", }, "permissions": { "SXZb": "edit", "SXZr": "view", "SxBt": "no access", "SxBZ": "edit", }, "slug": "Test-Page", "title": "Test Page", "updated_at": "2013-02-06T13:06:53Z", "url": "https://example.papyrs.com/Test-Page" }Get all pages
Get a list of all pages visible to the user making the request
GET /api/v1/pages/all/
Returns: A list of pages, ordered by creation date (newest page first).
[ { "category": "Main", "created_at": "2013-01-01T03:17:54Z", "created_by": "Mary", "id": "SXZp", "is_public": 0, "slug": "Some-example-page", "tags": [], "title": "Some Example Page", "updated_at": "2013-01-02T20:46:06Z", "url": "https://example.papyrs.com/Some-example-page" }, { "category": "Main/Bizdev", "created_at": "2012-08-13T02:50:49Z", "created_by": "John", "id": "SXJj", "is_public": 0, "slug": "Customer-Leads", "tags": ["Sales"], "title": "Customer Leads", "updated_at": "2013-01-10T19:38:59Z", "url": "http://example.papyrs.com/Customer-Leads" } ]Delete a Page
POST /api/v1/pages/delete/(#page_id)/
Returns:
{"deleted": true, "id": "(#page_id)"}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 standard layout is used.
- notifications is optional. If omitted, only users who have My Preferences > Notifications > Automatically subscribe to notifications for new pages
enabled will have notifications turned on for this page. When omitted and a default template is set for this group, its notification settings defaults are used.
When provided, notification values must be either
on
oroff
. The keys represent user IDs, which can be found using the People API (or Get a Page on an existing page).
- permissions is optional. If omitted, only Administrators will have
edit
access, and all other usersno access
. When ommitted and a default template is set for this group, permissions will start with the default template's permissions. When provided, permission values must be eitherno access
,view
oredit
. The keys represent user IDs, which can be found using the People API (or Get a Page on an existing page).
{ "title": "Hello World", "json": [ [ {"classname": "Paragraph", "val": "Hello World!"} ], [ ] ], "layout": [ [ [ 8, 1 ], [ 4, 1 ] ] ], "notifications": { "SXZb": "off", "SXZr": "on", "SxBt": "on", "SxBZ": "on", }, "permissions": { "SXZb": "edit", "SXZr": "view", "SxBt": "no access", "SxBZ": "edit", }, "category": "Some Folder/Sub Folder" }
Returns: the same as "Get a Page":
{ "category": "Some Folder/Sub Folder", "created_at": "2013-02-06T13:24:11Z", "created_by": "Wim", "id": "SKvS", "is_public": false, "json": [ [ { "classname": "Paragraph", "html": "Hello World!", "id": "SQRv", "text": "Hello World!" } ], [] ], "layout": [ [ [ 8, 1 ], [ 4, 1 ] ] ], "notifications": { "SXZb": "off", "SXZr": "on", "SxBt": "on", "SxBZ": "on", }, "permissions": { "SXZb": "edit", "SXZr": "view", "SxBt": "no access", "SxBZ": "edit", }, "slug": "Hello-World", "title": "Hello World", "updated_at": "2013-02-06T13:24:11Z", "url": "https://example.papyrs.com/Hello-World" }
Records
List all records for a pageGET /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.
The following optional parameters can be used for pagination:
Parameter | Description |
---|---|
page |
Returns the Nth page of results, from new to old. Default: 0 Example: /api/v1/search/query/?page=10 |
items_per_page |
The number of items to return, between 1 and 250 Default: 50 Example: /api/v1/search/query/?page=5&items_per_page=10 |
Example output:
[ [ { "field": "ID", "value": 1 }, { "field": "Created at", "value": "16/10/2018 18:42" }, { "field": "Created by", "value": "Mark Smith" }, { "field": "Example Field", "value": "Some value" }, { "field": "Another Field", "value": "Another value" } ], [ { "field": "ID", "value": 2 }, { "field": "Created at", "value": "16/10/2018 18:42" }, { "field": "Created by", "value": "Mark Smith" }, { "field": "Example Field", "value": "Another form record" }, { "field": "Another Field", "value": "Another value in the second record" } ] ]
Widgets
The Widgets API can be used to get, delete and create individual widgets on a page.
Get a WidgetGET /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:
{ "classname": "Paragraph", "text": "This is some example test, this is bold!", "html": "This is some example test, this is <b>bold</b>!", "id": "SQRc" }
{ "classname": "Heading", "text": "Welcome!", "html": "Welcome!", "id": "SQRs" }
{ "classname": "Attachment", "files": [ { "filename": "Important Document.pdf", "size": 483912, "url": "https://api-example.papyrs.com/file/attachment/SKMm/Important_Document.pdf", "vanity_size": "472 KB" }, { "filename": "Info.txt", "size": 17216, "url": "https://api-example.papyrs.com/file/attachment/SKMq/Info.txt", "vanity_size": "16 KB" } ], "id": "SQRt" }Create new Text box or Heading Widget on a Page
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:Parameter | Description | Default |
---|---|---|
format |
Describes 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:
{"widget": {"val": "Hello World!\nTest"}}
Returns: the same as "Get a Widget"
{ "classname": "Paragraph", "text": "Hello World!Test", "html": "Hello World!<br>Test", "id": "SQRf" }Update existing Text box or Heading Widget on a Page
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:Parameter | Description | Default |
---|---|---|
format |
Describes 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:
{"widget": {"val": "Hello World!\nTest Updated"}}
Returns: the same as "Get a Widget"
{ "classname": "Paragraph", "text": "Hello World!Test Updated", "html": "Hello World!<br>Test Updated", "id": "SQRf", "version_of_id": "SZlV" }Create new Attachment Widget on a Page
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:
curl -H "User-Agent: MyApp" \ -F file=@test.txt \ https://example.papyrs.com/api/v1/page/SKTL/attachment/create/?auth_token=123456789012
Returns: the same as "Get a Widget"
{ "classname": "Attachment", "files": [ { "filename": "test.txt", "size": 483912, "url": "https://api-example.papyrs.com/file/attachment/SKMm/test.txt", "vanity_size": "472 KB" } ] "id": "SQRf" }Updating an existing Attachment Widget on a Page
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:
curl -H "User-Agent: MyApp" \ -F file=@test2.txt \ https://example.papyrs.com/api/v1/page/SKTL/attachment/update/SQRf/?auth_token=123456789012
Returns: the updated Attachment widget, in the same format as "Get a Widget"
{ "classname": "Attachment", "files": [ { "filename": "test.txt", "size": 483912, "url": "https://api-example.papyrs.com/file/attachment/SKMm/test.txt", "vanity_size": "472 KB" }, { "filename": "test2.txt", "size": 48391, "url": "https://api-example.papyrs.com/file/attachment/SKMo/test2.txt", "vanity_size": "47 KB" } ] "id": "SQRf" }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:
{"deleted": true, "id": "SQcK"}
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 queryGet 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:Parameter | Description |
---|---|
q |
The 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 value | Description |
---|---|
Page | Result is a page |
File | Result is a file |
Contact | Result is a person from the People Directory |
Form | Result is a form entry |
Comment | Result is a comment |
{ "results": [ { "desc": "Information for Employees", "icon": "status-icon-page", "weight": 1646, "lnk": "/Information-for-Employees", "cat": "Page", "id": "xF8a" } ] }
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 peopleGet a list of all people in your account (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.
GET /api/v1/people/all/
Returns: A list of people, ordered by join date (newest user first).
[ { "attributes": { "Bio": "Degree in Corporate Finance. Responsible for all finances at Acme. Reimbursement approvals.", "Birthday": "03/17/1980", "City": "San Francisco", "Country": "US", "Email": "jane@acme.inc.example.com", "Group": "SF Office (HQ)", "Joined at": "10/16/2013", "Name": "Jane Smith", "Position": "CFO", "State": "CA", "Street": "13493 Main Street", "Telephone (Home)": "", "Telephone (Mobile)": "789-192", "Telephone (Work)": "", "Twitter": "<a href='https://twitter.com/Twitter'>AcmeJane</a>", "Website": "<a href='http://www.example.com'>Example</a>", "Zipcode": "92922" }, "avatar_large": "https://media.papyrs.com/avatars/123456789.png", "distinguished_name": "CN=Jane Smith,OU=SF Office,OU=Users,DC=AcmeInc,DC=local", "id": "SxrX", "role_id": "normal", "subgroup_id": "SXZH", "waiting_invite": true } ]
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 userPermanently delete a user from your account. Site adminstrators only.
POST /api/v1/people/delete/(#user_id)/
Returns:
{"deleted": true, "id": "(#user_id)"}
Feed
The Feed API can be used to post comments to the Activity Stream.
Post to the Activity StreamPOST /api/v1/feed/post/
Requests:
{"msg": "Your new message!"}
Returns:
{ "c": "Your new message!", "by": "Wim", "a": "/static/avatar.png", "unsafe_c": "Your new message!", "id": 22171 }Post to a discussion stream on a specific page
POST /api/v1/feed/post/(#page_id)/
You can use the API to post a comment to any page with a Discussion widget. The request and response are the same as for posting to the Activity Stream.