Ponder API v2.1

Base URI

https://www.ponder.co/api/2.1
Documentation
Getting Started

Registering your application

To integrate with Ponder, contact us to register your application. We will provide you with an appId and secret, which you’ll use for authentication.

Setting up your users

The next step will be to register your users with Ponder. Ponder organizes users into groups. Each user must be in at least one group, so the first step is to create a group via the Groups API.

Once you have a group, you can add your users via the [SSO API](#Authentication_Single-Sign-On-(SSO), which is covered in the next section.

Authentication

There are 2 mechanisms for authenticating with the Ponder API, which support application-level and user-level tasks.

Application

Application-level authentication is required for administrative tasks such as creating users and initializing groups. To authenticate as this level, simply include the Authorization header on your request with value AppSecret <your secret>. You should only use this mechanism on server-side calls to avoid exposing your secret.

User

User-level authentication allows you to make requests on behalf of a user, such as getting activity data. To authenticate at this level, simply include the Authorization header on your request with value UserToken <user token>.

Embedding Ponder on Your Site

You can embed the Ponder experience on your site. Here’s an example.

Adding Ponder to your pages

Add the following to the end of <body> on the pages you’d like to include Ponder.

<body>
...
<!-- This is where the Ponder app will live -->
<div id="ponder-embed"></div>
<!-- You can OPTIONALLY include the jquery and jquery.scrollTo libraries.
     Navigating to responses will be a little smoother if you include these,
     but the core functionality will work either way. -->
<script src="jquery.scrollTo.js"></script>
<!-- This is the Ponder embed script. It adds `Ponder` to `window` -->
<script src="https://www.ponder.co/embed/x.y.z/0.1.11/embed-ponder.js"></script>
<!-- We're almost there.  
     We just need to grab an SSO token to authenticate your users with Ponder,
     (more on that below) and initialize the app. -->
<script>
// Set up the configuration data
var config = {
  // Authentication - we'll fill this in below
  sso: {
    jwt: 'token will go here',
    appId: 'your public appId'
  },
  type: 'text',
  // URL to the embed app
  embedApp: 'https://www.ponder.co/embed/x.y.z/0.1.11/',
  // Unique URL to this content
  url: window.location.href,
  // Metadata about the page
  pageMeta: {
    title: "Title of your content"
  }
};
// Get SSO data from your server to authenticate your user
$.get('/sso/', function (ssoData) {
  config.sso = ssoData; // { jwt: <token>, appId: <your appId> }
  // Initialize the app
  Ponder.init(config);
});
</script>
</body>

Generating the SSO token

Ponder requires users to be authenticated. We obviously don’t want users to have to login to Ponder after you have already authenticated them, so instead you’ll pass an SSO token to our app when you initialize it.

The token is a JSON web token. You’ll need to generate these tokens on your server because they are encoded with your AppSecret. Here are the steps:

  1. Create a JSON object with the SSO data. This object has the same schema as the [/core/sso/ API](JSON web token
  2. Add an expiration date (Numeric Date format) exp. This prevents the token from being used indefinitely. Ponder will not accept a token if this value is more than 60 seconds from the time it receives the token.
# Pseudo-code
payload = {
    # These are the values from the SSO API
    "yourUserId": user.id,
    "username": user.username,
    "groupMembership": {
        "group": "your-group-id",
        "role": <0 for admin, 1 for member>
    },
    # Here's the expiration date
    "exp": datetime.utcnow(),
}
  1. Encode and sign the object via JWT with HS256 and your AppSecret. There are libraries in a bunch of languages that will do the work for you.
import jwt
token = jwt.encode(payload, SECRET) # HS256
  1. Return the token and your public appId
return Response({
    "appId": APP_ID,
    "token": token
})
Storing ids in your system

If you are storing our user and group ids in your system, you should allow for 32 characters (e.g. varchar(32) or the equivalent). New-style ids are 11 character strings, however old-style ones can be up to 32 characters.

Working with the video APIs

The video API identifies videos by a ‘content id’, which lives in the cid field. Here’s an example: youtube://cUAsGr6KM2E. The format is <source>://<video_id>.

Supported sources:

  • Youtube: youtube://<video_id>

The video id is the value of the v= query parameter in youtube urls: www.youtube.com/watch?v=cUAsGr6KM2E&morestuff

  • Vimeo: vimeo://<video_id>

Vimeo has a couple different URL formats, but the video id is a number that appears at the end of the URL: https://vimeo.com/100350511. (If you’re not sure, navigate to https://vimeo.com/<the video id> and if it takes you to the video, you’re good to go.)

If you’d like to use videos from another source with Ponder, let us know.

API Methods
Users and Groups
GET /core/groups/
POST /core/groups/
POST /core/sso/
GET /core/embed/config/
POST /core/memberships/add/
POST /core/memberships/remove/
List groups
GET /core/groups/

Returns a list of groups based on authentication.

  • User-level - this is a list of groups the user is a member of.
  • Application-level - this is a list of groups that the Application has access to.

Responses

200 OK
Body
Array of CRUD Group
Create and Update Groups
POST /core/groups/

The groups API allows you to create and update groups. It can be called at the application-level or on behalf of a user.

When called on behalf of a user:

  • If creating, the user is automatically added as a group admin.
  • If updating, the user must already be a group admin, otherwise the call will fail.

Request body

Responses

200 OK

Examples

POST https://www.ponder.co/api/2.1/core/groups/ HTTP/1.1 

Content-Type: application/json

{
    "id": "ULVJNG1ciPI",
    "name": "ENG 101",
    "tnt": {
        "themes": [
            {
                "name": "Critical Thinking",
                "themes": [
                    "Moral Hazard",
                    "Correlation",
                    "Causation"
                ]
            }
        ]
    }
}
Single Sign On
POST /core/sso/

This API creates a Ponder user for your users and returns that user’s userId and token. It must be authenticated with your application secret.

Request body

Object
yourUserId
string

An id that uniquely identifies the user in your application. Behind the scenes in our system, we do a lookup on userId,appId to determine whether to create a user or update an existing one. This value can be a maximum of 32 characters.

Example:
12
username
string

A friendly username. This value can be between 4 and 15 characters, alphanumeric and -_@.. Unlike userId, there is no lookup on this value.

Example:
john_h_doe
groupMembership
Object

A group that the user will be a member of. Ponder requires that all users are a member of at least one group. You can add other memberships via the add group membership API.

group
string

Id of one of your existing groups.

Example:
ULVJNG1ciPI

The role of the membership

Responses

200 OK
Body
Object
userToken
string

A token that you can use to authenticate requests on behalf of the user.

userId
string

This is Ponder’s userId, which will identify the user in all the other APIs.

This value is unique across Ponder, and is not the same as your internal userId that you use to call the SSO API.

Example:
4A7C8C368A4F4BFCB8C39E36D018B026
yourUserId
string

Echos back your app’s userId

Example:
12
Embed Configuration
GET /core/embed/config/

Returns configuration information - particularly groups and their sentiments and themes - required for embedding Ponder. This endpoint is only accessible via user token authentication.

Responses

200 OK
Body
Object
username
string

The username of the requesting user

Example:
tony
userId
string

The userId of the requesting user

Example:
4A7C8C368A4F4BFCB8C39E36D018B026
groups

An array of groups the user can tag in responses.

An array of the sentiment set metadata for those sets referenced in groups.tnt.

Examples

GET https://www.ponder.co/api/2.1/core/embed/config/ HTTP/1.1 

HTTP/1.1 200 OK 

Content-Type: application/json

{
    "username": "tony",
    "userId": "4A7C8C368A4F4BFCB8C39E36D018B026",
    "groups": [
        {
            "id": "ULVJNG1ciPI",
            "name": "ENG 101",
            "tnt": {
                "themes": [
                    {
                        "name": "Critical Thinking",
                        "themes": [
                            "Correlation",
                            "Causation"
                        ]
                    }
                ],
                "thtSet": 1
            }
        }
    ],
    "thtSets": [
        {
            "id": 1,
            "name": "default",
            "thts": [
                {
                    "id": 973739,
                    "evalType": "REACT",
                    "short": "{ chuckle }",
                    "long": "Heh.",
                    "firstPerson": "I am amused",
                    "secondPerson": "You are amused",
                    "thirdPerson": "is amused",
                    "thirdPlural": "are amused",
                    "inBaseSet": false
                }
            ]
        }
    ]
}
Add group membership
POST /core/memberships/add/

Creates or updates a group membership. This endpoint is only accessible via Application Secret authentication.

Request body

Object
user
string

The Ponder userId of the user to add to the group.

Example:
4A7C8C368A4F4BFCB8C39E36D018B026
group
string

Id of the group to add the user to.

The role for the membership.

Responses

200 OK
Remove group membership
POST /core/memberships/remove/

Removes a group membership. If you want to change a group member’s role, use Add group membership instead.

A user must be in at least 1 group, so this call will fail (HTTP status code 400) if you attempt to remove the user from its last group.

Request body

Object
user
string

The Ponder user id of the user to remove from the group.

Example:
group
string

The group id to remove the user from.

Responses

200 OK
Text
POST /text/responses/get/
POST /text/responses/update/
POST /text/responses/remove_group/
Get responses for a resource
POST /text/responses/get/

Returns responses for a resource.

Request body

Object
url
string

A URL of the resource

Example:
http://www.nytimes.com/2014/01/21/world/americas/venezuela-gasoline-prices.html?_r=1
meta

Metadata from the page. This is used to correctly map what may be multiple URLs that point to the same content to a single value.

Responses

200 OK
Body
Object
threads

An array of the threads on this resource.

url
string

The URL from the request is echoed back.

Example:
http://www.nytimes.com/2014/01/21/world/americas/venezuela-gasoline-prices.html?_r=1
Create or update responses
POST /text/responses/update/

Creates or updates a response. This method can only be called in the context of a user.

Request body

Object
groups
string

An array of groupIds that were tagged.

Example:
lxytKQIehyg
id
string nullable

The response id if updating; omit this to create a new response.

meta
note
string

The elaboration. (Maximum 250 characters)

Example:
...like the Costco hotdog
themes
string

An array of theme terms that were tagged.

Example:
Subsidy
selection
string

The selection text. (Maximum 600 characters)

Example:
Mr. Maduro has not said when or how much he will raise the price, which has been frozen for 15 years
threadId
string nullable

If the response is a reply, this is set to the id of the head response. For new responses, this will be null.

Example:
tht
string

id of the sentiment that was selected.

Example:
3CD8ED
ts
string

UTC timestamp in ISO format

Example:
2015-03-11T23:05:00.069Z
url
string

URL of the page containing the selection.

Example:
http://www.nytimes.com/2014/01/21/world/americas/venezuela-gasoline-prices.html?_r=1

Responses

200 OK
Body
Object
id
string

The id of the response that was created or updated.

Example:
54663fa54fbf94259696e93e

Examples

POST https://www.ponder.co/api/2.1/text/responses/update/ HTTP/1.1 

Content-Type: application/json

{
    "groups": [
        "lxytKQIehyg"
    ],
    "id": null,
    "meta": {
        "canonical": "http://www.nytimes.com/2014/01/21/world/americas/venezuela-gasoline-prices.html"
    },
    "note": "...like the Costco hotdog",
    "themes": [
        "Subsidy"
    ],
    "selection": "Mr. Maduro has not said when or how much he will raise the price, which has been frozen for 15 years",
    "threadId": null,
    "tht": "3CD8ED",
    "ts": "2015-03-11T23:05:00.069Z",
    "url": "http://www.nytimes.com/2014/01/21/world/americas/venezuela-gasoline-prices.html?_r=1"
}

HTTP/1.1 200 OK 

Content-Type: application/json

{"id": "54663fa54fbf94259696e93e"}
Remove response from groups
POST /text/responses/remove_group/

Removes a response from one or more groups. Both the user who created the response, and an App or User in the admin role of the groups can remove a response from a group. Removing a response from all its groups will effectively delete it.

Request body

Object
groups
string

An array of groups to remove the response from.

Example:
ULVJNG1ciPI
id
string

Id of the response to modify

Example:
560ecf4f56c02c0a20b97451
ts
string date

UTC timestamp in ISO format for this request. e.g. new Date().toISOString()

Example:
2015-03-11T23:05:00.069Z
Video
POST /video/responses/
POST /video/responses/update/
POST /video/responses/remove_groups/
Get responses for a video
POST /video/responses/

Returns video responses for a video, optionally filtered by groups. You can call this API with either UserToken or AppSecret authentication. Responses will be limited to those tagged to groups that the user or app has access to.

Request body

Object
cid
string

Id of the content

Example:
youtube://cUAsGr6KM2E
groups
string

optional - An array of groups to filter on

Example:
ULVJNG1ciPI

Responses

200 OK
Body
Array of Video Response

Examples

POST https://www.ponder.co/api/2.1/video/responses/ HTTP/1.1 

HTTP/1.1 200 OK 

Content-Type: application/json

[
    {
        "cid": "youtube://cUAsGr6KM2E",
        "groups": [
            "ULVJNG1ciPI"
        ],
        "note": "",
        "tht": "3CD8ED",
        "time": 62,
        "themes": [
            "Moral Hazard"
        ],
        "ts": "2015-03-11T23:05:00.069Z",
        "type": 1,
        "userId": "4A7C8C368A4F4BFCB8C39E36D018B026",
        "thtObj": {
            "id": 973739,
            "evalType": "REACT",
            "short": "{ chuckle }",
            "long": "Heh.",
            "firstPerson": "I am amused",
            "secondPerson": "You are amused",
            "thirdPerson": "is amused",
            "thirdPlural": "are amused",
            "inBaseSet": false
        }
    }
]
Create and update responses
POST /video/responses/update/

Creates or updates a video response. This method can only be called in the context of a user.

There can be at most one response per user-video-time-type combination, such that if you submit multiple with these same parameters, it will overwrite the existing one.

Request body

Responses

200 OK

Examples

POST https://www.ponder.co/api/2.1/video/responses/update/ HTTP/1.1 

Content-Type: application/json

{
    "cid": "youtube://cUAsGr6KM2E",
    "groups": [
        "ULVJNG1ciPI"
    ],
    "note": null,
    "tht": "3CD8ED",
    "time": 62,
    "themes": [
        "Moral Hazard"
    ],
    "type": 1,
    "ts": "2015-03-11T23:05:00.069Z"
}
Remove video response from groups
POST /video/responses/remove_groups/

Removes a response from one or more groups. Both the user who created the response, and an App or User in the admin role of the groups can remove a response from a group. Removing a response from all its groups will effectively delete it.

Request body

Object
cid
string

Id of the video

Example:
youtube://cUAsGr6KM2E
groups
string

An array of the groups to remove the response from.

Example:
ULVJNG1ciPI
time
number

Time (in the video) in seconds.

Example:
62
ts
string

UTC timestamp in ISO format for this request.

Example:
2015-03-11T23:05:00.069Z

The response type.

Example:
1
userId
string

The userId that created the response.

Example:
4A7C8C368A4F4BFCB8C39E36D018B026

Responses

200 OK
Data Reference
Theme Module

A named set of themes that the user can choose from when creating responses.

Object
name
string
Example:
Critical Thinking
themes
Array of string
Example:
Moral Hazard
Types: Tnt
Tnt
Object
themes
Array of Theme Module

optional - An array of theme modules

thtSet
number

Id of the sentiment set

Example:
1
Types: CRUD Group
Page Meta

Metadata about a page.

Object
canonical
string

The canonical URL for this content. It may differ from the actual URL if the content is split over multiple pages or the URL contains extra query parameters.

Example:
http://www.nytimes.com/2014/01/21/world/americas/venezuela-gasoline-prices.html
title
string

The title of the content

Example:
Venezuela May Meet New Reality, and New Price, at the Pump
image
string

optional - The URL of an image for the content.

Example:
http://static01.nyt.com/images/2014/01/21/world/VENEZUELA/VENEZUELA-tmagSF.jpg
Thread

A thread is collection of responses on the same selection.

Object
head

The first response of the thread after any filters are applied. This response is also included as the first entry in the responses field.

responses
Array of Response

An array of the responses that compose the thread.

tntSummary
string

A friendly string that summarizes the thts and themes of the thread’s responses. The head response user and tht are excluded.

Example:
Tony and Alex are troubled. Tony filed this under Moral Hazard.
Response

A micro response on text.

Object
groups
Array of string

An array of tagged groups.

Example:
ULVJNG1ciPI
id
string

Id of the response.

Example:
54872d152393122b9afe0621
iurl
string

The URL for the resource. iurl excludes scheme (the http:// portion).

Example:
www.theatlantic.com/education/archive/2014/12/why-the-demise-of-field-trips-is-bad-news/383546/
maxts
string

The maximum timestamp of the response. This will be greater than mints if the user updates his/her response.

Example:
2014-12-09T17:10:54.293000
mints
string

The timestamp at which the response was created.

Example:
2014-12-09T17:10:54.293000
note
string

A 250 character elaboration

Example:
Correlation does not imply causation!!!
resId
string

The id of the resource

Example:
_plQd3JhYLw
selection
string

The selection text

Example:
But in a growing number of schools, field trips are now an incentive for good behavior, perfect attendance, or improved grades rather than cultural enrichment. That means the symphony takes a back seat to the local amusement park or bowling alley.
themes
Array of string

An array of tagged themes.

Example:
Correlation
threadId
string

unstable - Id of the response the user is replying to.

Example:
tht
string

Id of the sentiment.

Example:
41198F

Only in data coming from Ponder - Metadata about the sentiment in the tht field.

url
string

The URL of the page the responder was on when creating the response.

Example:
http://theatlantic.com/education/archive/2014/12/why-the-demise-of-field-trips-is-bad-news/383546/
userId
string

The userId of the responder.

Example:
77D4BF662E1B433286EC81A3EC2A577B
username
string

The username of the responder. In the ‘public’ version, this is replaced with the user’s group.

Example:
1Eyed-Undrtkr
Types: Thread
Sentiment (tht)

Metadata of the sentiment. The sentiment field is often abbreviated as tht in field names.

Object
id
string

The id of the sentiment.

Example:
973739
evalType
string

Sentiment type: Evalute|React|Understand

Example:
REACT
short
string

Short format. (This is the format that appears on the button in the response box.)

Example:
{ chuckle }
long
string

Long format

Example:
Heh.
firstPerson
string

1st person format

Example:
I am amused
secondPerson
string

2nd person format

Example:
You are amused
thirdPerson
string

Third person format

Example:
is amused
thirdPlural
string

Plural third person format

Example:
are amused
inBaseSet
boolean

config only - Sentiment sets support two tiers, and this value indicates whether the sentiment is in the base tier.

Example:
false
Video Response

A response on a video.

Object
cid
string

Id of the content.

Example:
youtube://cUAsGr6KM2E
groups
Array of string

An array of groups tagged in this response.

Example:
ULVJNG1ciPI
note
string

The elaboration (Maximum 250 characters)

tht
string

Id of the sentiment that was selected.

Video responses support a lighter-weight “bookmark” that does not require a sentiment, such that this value can be null.

Example:
3CD8ED
time
number

Time (in the video) in seconds

Example:
62
themes
Array of string

An array of tagged themes

Example:
Moral Hazard
ts
string

UTC timestamp in ISO format of when the response was made

Example:
2015-03-11T23:05:00.069Z

Type of the response

Example:
1
userId
string

Only in data coming from Ponder - The userId for the user who submitted the response.

In responses submitted to Ponder, userId is populated via the context of the authenticated user, so this field is ignored.

Only in data coming from Ponder - Metadata about the sentiment in the tht field.

CRUD Group

The CRUD representation of a Group

Object
id
string

The id of the group. Omitting this value will create a new group.

Example:
ULVJNG1ciPI
name
string

The name of the group. This can be up to 30 characters, but shorter is better.

Example:
ENG 101
tnt

Themes for the group.

Sentiment Set (ThtSet)

An ordered collection of sentiments. These sets make up the choices of sentiments when a user is creating a response.

Object
id
number

The set id.

Example:
1
name
string

The set name.

Example:
default
thts
Array of Sentiment (tht)

The ordered list of sentiments.

Group Member Role

Options for the type of relationship between a user and group.

string
Enumeration:
0

Admin

1

Member

Video Response Type

Options for the type of video responses.

string
Enumeration:
1

Full response with sentiment and optionally themes and note.

0

Lightweight “bookmark” with no sentiment, note, or themes.