API

In this document:

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!

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, 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).

Authenticated API calls

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 https://example.papyrs.com/pages/alphabetical/?json&auth_token=123456789012

Example GET request:
curl -H "Content-Type: application/json" \
     -H "User-Agent: MyApp" \
     https://example.papyrs.com/api/v1/pages/all/?auth_token=123456789012
Example 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=html
Example 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.text 
Error & 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 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:

{
    "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:

{
    "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 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.

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 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:

{
 "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 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:
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 people

Get 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 user

Permanently 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 Stream

POST /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.

Printer friendly docs