Introduction
Panoptes API is a crowdsourcing system based on serving subjects, images or other media, to volunteers and asking them to classify the subject based on a defined workflow for the subject type.
Authentication
Panoptes API provides an OAuth 2.0 authentication mechanism. (TODO: Describe Authentication Workflow).
How do I authenticate with the Zooniverse API?
Some requests to the Zooniverse API will respond without supplied authentication details as they are public but most require an authentication token to be supplied to access our systems as a known user.
This authentication token is known as a bearer token and is usually supplied as a HTTP Authorization
header with the value prefixed by Bearer
and then the token data. For example:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
The bearer tokens we produce are actually JWT tokens in and of themselves. This means that if you have a bearer token, you can unpack it, verify that it was signed by our servers, and find your user ID, your permissions and some other things.
Tools to interact with the API
You can use Postman, Paw, cURL or one of our official Zooniverse libraries to authenticate and create requests to the API:
- Python
- https://github.com/zooniverse/panoptes-python-client
- JavaScript
- https://github.com/zooniverse/panoptes-javascript-client
- Ruby
- https://github.com/zooniverse/panoptes-client.rb
Example using Postman
Postman is a graphical tool to help you make API calls.
How do you get a token?
POST /oauth/token HTTP/1.1
Content-Type: application/json
{
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}
from panoptes_client import Panoptes
client = Panoptes.connect(username='', password='')
print(client.get_bearer_token())
require 'rubygems'
require 'panoptes-client'
client = Panoptes::Client.new(auth: {client_id: CLIENT_ID, client_secret: CLIENT_SECRET})
response = client.panoptes.connection.get('/me')
auth = response.env.request_headers["Authorization"]
token = auth.gsub(/Bearer (.*)/, "\\1")
puts token
There are multiple ways to get an OAuth bearer token from our authentication system, we support most of the OAuth grant types to convert credentials to a token. However our system restricts non-vetted apps from using particular flows, e.g. password (mostly to stop phishing sites harvesting our user credentials).
The easiest to get started with is to use OAuth and the client credentials OAuth flow. To do this you will need to create an OAuth application with our system.
Complete the form like the image below:
Tick all the resource scopes you'll be needing access to (start with all). Once setup note your client ID and secret for that app and that this app will be linked to your user account. It is imperative that you do not share the OAuth application secret as it can gain access to your Zooniverse account as if you were using the system.
There are other OAuth flows that can be used to get bearer tokens, please email contact@zooniverse.org to find out more.
Setup postman to use the client credentials to get API bearer tokens
I won’t go into details on how to setup postman, there are lots of docs that help with this.
You will need to setup a request to https://signin.zooniverse.org/api/me
and under the authorization tab, select OAuth 2.0, and click the ‘Get New Access Token’ button. Complete the forms like the images below:
- Token name is used to identify the token in Postman, this is for your reference only
- Select the grant type to be ‘Client Credentials’
- Use the client ID from the OAuth application you setup at signin.zooniverse.org
- Same for client secret
- Scope is a lowercase, space separated list of all OAuth application scopes you selected at signin.zooniverse.org, in the image above for my testing app i only ticked user scope.
- All scopes - user project group collection classification subject medium organization translation public
- Client authentication - send credentials in the request body
- Press ‘Request Token’ button
- If you can’t get a token and get a 422 response from the API ensure your scopes match exactly the list you selected for the app at signin.zooniverse.org earlier.
- Use the Postman console to debug the requests
- If successful you’ll see a screen with an access token, scroll down and press the ‘Use Token’ button
Now the request will have the authentication token setup for use in postman.
Add extra Zooniverse API headers for each request
The Zooniverse API requires some extra headers to access the API endpoints, specifically setting the Accept and Content-Type headers.
Click on the ‘Headers’ tab and set the following header key value pairs as per the image below.
Accept: application/vnd.api+json; version=1
Content-Type: application/json
Without the above extra headers any response to API endpoints will return a HTTP 404 response status code.
Ready to send requests to the Zooniverse API
The request is now ready to run, click the ‘Send’ button to send the request to the Zooniverse API, you should see the response show up.
This response is to the https://signin.zooniverse.org/api/me endpoint and requests the information about the owner of the bearer token, i.e. ‘me’.
Debugging requests and responses
Again any request failures can be debugged using the postman console, here you get a detailed view each request / response that postman is sending.
Some common failure modes: 1. Can’t get a bearer token from OAuth application credentials + Ensure the app id and secret match exactly what is showing in https://signin.zoonivese.org/oauth/applications + Ensure the scopes match exactly, OAuth app has user selected, scopes should be ‘user public’ 0. Get a 404 on /api/* endpoints request + Ensure the extra Accept and content-type headers are set on the requests, without them the API won’t route requests properly.
JSON-API conventions
Resource(s) themselves
{
"users": [{
"id": 123,
...
}],
...
}
If you request a resource, you will find the results under a top-level key with
the plural name of the resource. So for instance, if you a single specific user,
you will find the user record under the users
key.
Links
{
"projects": [{
...,
"links": {
"workflows": [123],
"avatar": {"href": "/projects/123/avatar", "type": "avatars"},
...
}
}],
"links": {
"projects.workflows": {
"href": "/workflows?project_id={projects.id}",
"type": "workflows"
},
"projects.avatar": {
"href": "/projects/{projects.id}/avatar",
"type": "media"
},
...
}
}
Any resource returned will specify a list of linked resources under its links
attribute. Definition on where to request those linked resources can be found
under the top-level links
key (as opposed to the per-resource links
).
Pagination
{
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/users?page_size=2",
"previous_href": "/users?page=14page_size=2",
"next_href": "/users?page=2&page_size=2",
"last_href": "/users?page=14&page_size=2"
}
When requesting a list of resources, rather than a single resource, the
response will include a top-level meta
key. For performance reasons, results
are returned in pages. You can use the data under the meta
key to
automatically navigate these paginated results.
Including linked resources
TODO
Headers
Panoptes API sometime requires specific headers to be sent as part of requests.
All requests should set Accept: application/vnd.api+json; version=1
. You will receive a 404 Not Found
without it.
All PUT and POST requests should set Content-Type: application/vnd.api+json; version=1
or Content-Type: application/json
. You will receive a 415 Unsupported Media Type
without one of those two headers.
All PUT and DELETE requests should set the If-Match
header to the value of the ETag
header of the request where the resource was originally retrieved. You will receive a 428 Precondition Required
without the header and a 412 Precondition Failed
if the etags do not match.
Aggregations
{
"aggregations": [
{
"id": "1",
"href": "/aggregations/1",
"created_at": "2024-05-22T22:52:59.173Z",
"updated_at": "2024-05-22T22:52:59.181Z",
"uuid": "557ebcfa3c29496787336bfbd7c4d856",
"task_id": "9c963646-e7cd-4c5a-8749-c97086d416bd",
"status": "completed",
"links": {
"workflow": "2",
"user": "2"
}
}
],
"links": {
"aggregations.workflow": {
"href": "/workflows/{aggregations.workflow}",
"type": "workflows"
},
"aggregations.user": {
"href": "/users/{aggregations.user}",
"type": "users"
}
}
}
A single Aggregation resource object. This represents the automated aggregation by the external service by a user of a single workflow via the online Aggregation service.
An Aggregation has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
workflow_id | integer | read-only |
project_id | integer | read-only |
created_at | string | read-only |
updated_at | string | read-only |
user_id | integer | read-only |
uuid | string | The unique identifier of the aggregation run, used in the URLs of output files |
task_id | string | The Celery task ID, used to query the status of the backgrounded task on the aggregation service |
status | integer | created, pending, completed, failed |
List aggregations
GET /api/aggregations HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
Only lists aggregations where the active user has has edit permissions on the related project.
Any of the scopes may be further filtered using the project_id, workflow_id and user_id parameters.
Parameters
- page (optional, integer) ... index of the page to retrieve, 1 is default
- page_size (optional, integer) ... number of items on a page. 20 is default
- sort (optional, string) ... fields to sort by. updated_at is default
- project_id (optional, integer) ... only retrieve aggregations for a specific project
- workflow_id (optional, integer) ... only retrieve aggregations for a specific workflow
- user_id (optional, integer) ... only retrieve aggregations for a specific user
- include (optional, string) ... comma separated list of linked resources to return in the response
Retrieve a single Aggregation
GET /api/aggregations/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
A User may only retrieve Aggregations they have permission to access.
Parameters
id
(required, integer) ... integer id of the resource to retrieve
Create an Aggregation [POST]
POST /api/aggregations HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"aggregations": {
"links": {
"user": "3",
"workflow": "2"
}
}
}
Creating a new Aggregation will initiate a new batch aggregation run. A call out to the Aggregation Service is made and the newly created Aggregation resource is updated with the Aggregation Service's Celery background task ID so that its status can be checked.
Edit a single Aggregation [PUT]
PUT /api/aggregations/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"aggregations": {
"uuid": "557ebcfa3c29496787336bfbd7c4d856",
"status": "completed"
}
}
Aggregations are updated by the Aggregation Service when a run has succeeded or failed. A successful run will send a request to this endpoint and update the UUID generated by that run. This UUID is a 32-character lowercase hexadecimal string and can be used to construct the URL to download that run's output data.
The status can also be updated via this route (see the aggregations model) and can be the only attribute included.
Destroy a single Aggregation [DELETE]
DELETE /api/Aggregations/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
A user may destroy an Aggregation by ID if they have destroy permissions for the parent project.
Classifications
{
"classifications": [{
"id": 1001,
"created_at": "2014-08-24T22:24:32Z",
"updated_at": "2014-08-24T22:24:32Z",
"completed": false,
"metadata": {
"started_at": "2014-08-24T22:20:21Z",
"finished_at": "2014-08-24T22:24:31Z",
"user_agent": "cURL",
"user_language": "es_MX",
"workflow_version": "11.12"
},
"annotations": [
{
"task": "task-1",
"value": [10.4, 12.4, 13.2]
}
],
"links": {
"user": "1",
"subjects": ["10"],
"workflow": "81",
"project": "2"
}
}],
"links": {
"classifications.user": {
"href": "/users/{classifications.user}",
"type": "classifications"
},
"classifications.project": {
"href": "/projects/{classifications.project}",
"type": "projects"
},
"classifications.workflow": {
"href": "/workflows/{classification.workflow}",
"type": "workflows"
},
"classifications.subject": {
"href": "/subjects/{classifications.subjects}",
"type": "subjects"
}
},
}
A single Classification resource object. This represents a user's responses to a workflow's questions about a subject.
A classification has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
created_at | string | read-only |
updated_at | string | read-only |
completed | string | read-only |
metadata | hash | |
gold_standard | boolean | |
annotations | array(hash) |
Annotations is an array of maps of the form { "task": "task_key",
"value": "question answer" }
. Metadata contains additional information about a
classification including:
- started_at
- finished_at
- user_agent
- workflow_version
- user_language
List classifications
GET /api/classifications HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
Only lists classifications the active user has made or projects the user has edit permissions for.
Classifications have special collection routes that indicate the scope you would like to retrieve.
Possible options are:
/api/classifications/
default, will fetch the current user's past complete classifications./api/classifications/incomplete
will fetch the current user's past incomplete classifications./api/classifications/project
will fetch classifications from projects a user has 'edit' permissions for/api/classifications/gold_standard
will fetch gold standard classifications for all marked workflows
Any of the scopes may be further filtered using the project_id, workflow_id and user_group_id parameters.
Parameters
- page (optional, integer) ... index of the collection page, 1 is default
- page_size (optional, integer) ... number of items on a page. 20 is default
- sort (optional, string) ... fields to sort collection by. updated_at is default
- project_id (optional, integer) ... only retrieve classifications for a specific project
- workflow_id (optional, integer) ... only retrieve classifications for a specific workflow
- user_group_id (optional, integer) ... only retrieve classifications for a specific user group
- include (optional, string) ... comma separated list of linked resources to return with the collection
- last_id (optional, integer) ... only classifications with ids greater than
last_id
will be returned (/project
only, requires project_id)
Retrieve a single Classification
GET /api/classifications/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
A User may retrieve any classification, irrespective of the complete status.
Parameters
id
(required, integer) ... integer id of the resource to retrieve
Create a Classification [POST]
POST /api/classifications HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"classifications": {
"completed": false,
"metadata": {
"started_at": "2014-08-24T22:20:21Z",
"finished_at": "2014-08-24T22:24:31Z",
"user_agent": "cURL",
"user_language": "es_MX",
"workflow_version": "11.12"
},
"annotations": [
{
"task": "task-name",
"value": "Any type: string, hash, array, etc"
}
],
"links": {
"subjects": ["11"],
"workflow": "81",
"project": "2"
}
}
}
Create a classification by providing a JSON-API formatted object, that must include metadata, annotations and a links hash. Optionally, it may include the completed field, which if not included defaults to true. The completed field is used to store half-completed classifications, so the user can later continue from where they stopped.
The links hash must contain a subjects hash, a project and a workflow. The metadata hash must contain all the keys specified in the example. Please note, the workflow_version should be the value returned from the specific workflow representation. The annotations array must be in the format specified in the example, i.e. an array of objects, containing a task and a value. The task can be anything and must not necessarily align with the tasks of the workflow (even though that is generally not advised).
Edit a single Classification [PUT]
PUT /api/classifications/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"classifications": {
"annotations": [
{
"task": "task-1",
"value": [10.4, 12.4, 13.2]
},
{
"task": "workflow-2",
"value": "fishy"
}
],
"completed": true
}
}
A User may modify an incomplete classification. It should be marked as completed when done.
The annotations attributes must be returned as a full representation of the annotations array.
Destroy a single Classification [DELETE]
DELETE /api/classifications/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
A User may delete an incomplete classification.
Collection preferences
{
"collection_preferences": [{
"id": "942",
"preferences": {
"display": "grid"
},
"created_at": "2014-03-20T06:23:12Z",
"updated_at": "2014-04-21T08:22:22Z",
"links": {
"user" : "30",
"collection": "11"
}
}],
"links": {
"collection_preferences.user": {
"href": "/user/{collection_preferences.user}",
"type": "users"
},
"collection_preferences.collection": {
"href": "/collections/{collection_preferences.collection}",
"type": "collections"
}
}
}
A Collection Preference resource captures a user's settings for a particular collection.
It has the following attributes:
- id
- created_at
- updated_at
- preferences
id, created_at, and updated_at are set the by the API. Collection preferences are only visible to user they belong to.
List collection preferences
All collections add a meta attribute hash containing paging information.
Parameters
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
- sort (optional, string) ... field to sort by
- user_id (optional, integer) ... user_id to see preferences for
- collection_id (optional, integer) ... collection_id to see preferences for
- include (optional, string) ... comma separated list of linked resources to load
Retrieve a single CollectionPreference [GET]
Parameters
- include (optional, string) ... comma separated list of linked resources to load
Edit a CollectionPreference [PUT]
PUT /api/collection_preferences/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"collection_preferences": {
"preferences": {
"receive_updates": false,
}
}
}
Only the owning user may edit a Collection Preference resource. The preferences field may be edited. Editing the preferences field requires a full representation of the preferences object to be sent.
Create a CollectionPreference [POST]
POST /api/collection_preferences HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"collection_preferences": {
"preferences": {
"display": "grid"
},
"links": {
"collection": "1"
}
}
}
Creating a Collection Preference requires only a link to a collection. Optionally an object of settings for preferences may be included.
Since a user can only create, read, or modify their own preferences the currently logged in user is always set as the linked user on creation.
CollectionRole
{
"links": {
"collection_roles.owner": {
"href": "/{collection_roles.owner.href}",
"type": "owners"
},
"collection_roles.collection": {
"href": "/collections/{collection_roles.collection}",
"type": "collections"
}
},
"meta": {
"collection_roles": {
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/collection_roles?page_size=2",
"previous_href": "/collection_roles?page=14page_size=2",
"next_href": "/collection_roles?page=2&page_size=2",
"last_href": "/collection_roles?page=14&page_size=2"
}
},
"collection_roles": [{
"id": "942",
"roles": ["collaborator"],
"created_at": "2014-03-20T06:23:12Z",
"updated_at": "2014-04-21T08:22:22Z",
"links": {
"collection": "11",
"owner": {
"id": "4",
"display_name": "Owner 4",
"type": "user_groups",
"href": "user_groups/4"
}
}
},{
"id": "949",
"roles": ["viewer"],
"created_at": "2014-08-20T06:23:12Z",
"updated_at": "2014-09-21T08:22:22Z",
"links": {
"collection": "81",
"owner": {
"id": "1",
"display_name": "Owner 1",
"type": "users",
"href": "users/1"
}
}
}]
}
Resources related to Roles for Panoptes Collections A Collection Role resources contains an array of roles assigned to a user for a particular collection.
It has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
created_at | string | read-only |
updated_at | string | read-only |
roles | array(string) |
id, created_at, and updated_at are set the by the API. Collection roles are visible to the collection owner and the user given roles.
Collection Role Types
collaborator
- full access to edit or delete a collectionviewer
- may view a private collection
List All Collection Roles
A Collection of CollectionRole resources.
All collections add a meta attribute hash containing paging information.
CollectionRoles are returned as an array under collection_roles.
GET /api/collection_roles HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
- sort (optional, string) ... field to sort by
- user_id (optional, integer) ... user_id to see roles for
- collection_id (optional, integer) ... collection_id to see roles for
- include (optional, string) ... comma separate list of linked resources to load
Retrieve a single CollectionRole
GET /api/collection_roles/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer identifier of the collection role resource
- include (optional, string) ... comma separate list of linked resources to load
Create a CollectionRole
POST /api/collection_roles/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"collection_roles": {
"roles": ["collaborator"],
"links": {
"collection": "1",
"user": "842"
}
}
}
Creating a Collection Role resource requires a link to a user and a collection. You may also include an array of roles.
Edit a CollectionRole
PUT /api/collection_roles/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"collection_roles": {
"roles": ["viewer"]
}
}
A user with permissions to edit a collection may modify roles for other users in the collection. A user without edit permissions may not edit their own roles.
Editing requires sending a full representation of the roles array.
Collections
{
"links": {
"collections.subjects": {
"href": "/subjects{?collection_id=collections.id}",
"type": "subjects"
}
},
"collections": [{
"id": "101",
"created_at": "2014-04-20T06:23:12Z",
"updated_at": "2014-04-20T06:23:12Z",
"name" : "flowers",
"display_name": "Lots of Pretty flowers",
"default_subject_src": "panoptes-uploads.zooniverse.org/production/subject_location/hash.jpeg",
"links": {
"owner": {
"id": "10",
"display_name": "Owner 10",
"href": "/users/10",
"type": "users"
}
}
}]
}
A collection is a user curated set of subjects for a particular project.
It has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
display_name | string | |
name | string | |
created_at | string | read-only |
updated_at | string | read-only |
default_subject | id |
id, created_at, and updated_at are set by the API.
List all collections
GET /api/collections HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
- sort (optional, string) ... field to sort by
- owner (optional, string) ... string name of either a user or user group to filter by
All collections add a meta attribute hash containing paging
information.
Collections are returned as an array under collections.
Retrieve a single collection
GET /api/projects/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer id of the resource to retrieve
- display_name (string) ... project name filter
Create a Collection
A Collection only needs a display name to be created. By default name will be the underscored and downcased version of display_name, and the current user will be set as the owner.
Optionally a create request may include name, a link to an owner, and links to subjects.
POST /api/collections HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"collections": {
"display_name": "flowers",
"links": {
"owner": {
"id" : "10",
"display_name": "Owner 10",
"type": "user_groups",
"href": "/user_groups/10"
}
}
}
}
Edit a Collection
PUT /api/collections/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"collections": {
"name": "flower_power",
}
}
A user may edit a collection they are the owner of or have edit permissions for. A user may edit a collection's name, or display_name, and may also send a full representation of a collections subject links or a single subject id to set the default subject.
Sending subject links through a put is not recommend, especially if a collection has many subjects.
Removing subjects from a collection does not destroy the subject record.
Destroy a Collection
DELETE /api/collections/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
A user who is the owner of a collection or who has destroy permissions for a collection, may delete it.
Add subject links
Add subjects to a collection.
POST /api/collections/123/links/subjects HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"subjects": ["1", "2"]
}
A user is permitted to add subject if they are the collection owner or have edit permissions.
Remove subject links
DELETE /api/collections/123/links/subjects/1,2 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
Remove subjects from a collection.
A user is permitted to remove subjects if they are the collection owner or have edit permissions.
- Parameters
- id (required, integer) ... id of collection to edit
- link_ids (required, string) ... comma separated list of ids to remove
Add default subject link
POST /api/collections/123/links/default_subject HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"default_subject": "1"
}
Links a default subject to a collection. This subject's first media
location URL will be included in the serialized collection and used
as the thumbnail. Update this attribute with null
to use the first
subject in the linked list instead.
A user is permitted to add a default subject if they are the collection owner or have edit permissions.
Memberships
{
"links": {
"memberships.user_group": {
"href": "/user_groups/{memberships.user_group}",
"type": "user_groups"
},
"memberships.user": {
"href": "/users/{memberships.user}",
"type": "users"
}
},
"meta": {
"memberships": {
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/memberships?page_size=2",
"previous_href": "/memberships?page=14page_size=2",
"next_href": "/memberships?page=2&page_size=2",
"last_href": "/memberships?page=14&page_size=2"
}
},
"memberships": [{
"id": "101",
"created_at": "2014-04-20T06:23:12Z",
"updated_at": "2014-04-20T06:23:12Z",
"state": "active",
"roles": ["group_admin"],
"links": {
"user": "12",
"user_groups": "31"
}
},{
"id": "111",
"created_at": "2014-04-20T06:23:12Z",
"updated_at": "2014-04-20T06:23:12Z",
"state": "inactive",
"roles": [],
"links": {
"user": "12",
"user_groups": "20"
}
}]
}
A membership represents and user's status in a group and their role within the group.
It has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
created_at | string | read-only |
updated_at | string | read-only |
state | string | |
roles | array(string) |
id, created_at, and update_at are assigned by the API.
- Membership state can be:
- "invited"
- "active"
- "inactive"
When a user is added to a group, their state is set to "invited". After they take action to join the group their state becomes "active". A User who leaves a group has their state set to "inactive".
List All Memberships
GET /api/memberships HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... index of the page to retrieve 1 by default
- page_size (optional, integer) ... number of items per page 20 by default
- sort (optional, string) ... field to sort by, id by default
- user_id (optional, integer) ... filter list to memberships for a user
- user_group_id (optional, integer) ... filter list to memberships for a user group
All memberships add a meta attribute hash containing paging information.
Memberships are returned as an array under memberships.
Retreive a Membership
GET /api/memberships/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer id of the resource to retrieve
Create a Membership
POST /api/memberships HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"memberships": {
"join_token": "decafbad",
"links": {
"user": "10",
"user_group": "11
}
}
}
A membership creation request must include a link to a user and to a user_group, although currently the linked user must always be the current user. The request must also include the secret join_token of the user_group as an attribute of the membership (although this property is not persisted).
Edit a Membership
PUT /api/memberships/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"memberships": {
"state": "inactive"
}
}
A user can ordinary only change their membership state. A user with user group edit permissions can change the membership's roles.
Destroy a Membership
DELETE /api/memberships/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
Destroying a membership only sets the state to inactive. A user may destroy their own memberships and a user with edit permission in a user group may destroy membership for that group.
Organizations
{
"organizations": [
{
"id": "5",
"display_name": "United Federation of Projects",
"description": "Every project in the galaxy",
"introduction": "Hello and welcome to the UFP",
"title": "United Federation of Projects",
"href": "/organizations/5",
"primary_language": "en",
"listed_at": null,
"listed": true,
"slug": "user/slug",
"urls": [
{
"url": "https://twitter.com/UFP",
"path": "United Federation of Twitter",
"site": "twitter.com/",
"label": ""
}
],
"categories": [],
"announcement": "Oh Gosh!",
"links": {
"organization_contents": [
"5"
],
"organization_roles": [
"9999"
],
"projects": [
"1",
"2"
],
"owner": {
"id": "811067",
"display_name": "meredithspalmer",
"type": "users",
"href": "/users/811067"
},
"pages": [
"5"
],
"avatar": {
"href": "/organizations/5/avatar",
"type": "avatars",
"id": "27687087"
},
"background": {
"href": "/organizations/5/background",
"type": "backgrounds",
"id": "30335947"
},
"attached_images": {
"href": "/organizations/5/attached_images",
"type": "attached_images"
}
}
}
],
"links": {
"organizations.attached_images": {
"href": "/organizations/{organizations.id}/attached_images",
"type": "media"
},
"organizations.organization_contents": {
"href": "/organization_contents?organization_id={organizations.id}",
"type": "organization_contents"
},
"organizations.organization_roles": {
"href": "/organization_roles?organization_id={organizations.id}",
"type": "organization_roles"
},
"organizations.projects": {
"href": "/projects?organization_id={organizations.id}",
"type": "projects"
},
"organizations.pages": {
"href": "/organizations/{organizations.id}/pages",
"type": "organization_pages"
},
"organizations.owner": {
"href": "/{organizations.owner.href}",
"type": "owners"
},
"organizations.avatar": {
"href": "/organizations/{organizations.id}/avatar",
"type": "media"
},
"organizations.background": {
"href": "/organizations/{organizations.id}/background",
"type": "media"
}
},
"meta": {
"organizations": {
"page": 1,
"page_size": 20,
"count": 1,
"include": [],
"page_count": 1,
"previous_page": null,
"next_page": null,
"first_href": "/organizations",
"previous_href": null,
"next_href": null,
"last_href": "/organizations"
}
}
}
An Organization is a collection of projects that are related by dicipline, research group
It has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
display_name | string | |
title | string | |
description | string | |
introduction | string | |
slug | string | |
primary_language | string | |
listed_at | datetime | |
activated_state | integer | |
created_at | datetime | read-only |
updated_at | datetime | read-only |
urls | jsonb | |
listed | boolean | |
categories | string | |
available_languages | array(string) | |
background | string | |
avatar | string |
List All Organizations
GET /api/organizations HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
- sort (optional, string) ... field to sort by
- owner (optional, string) ... string owner name of either a user or a user group to filter by.
- include (optional, string) ... comma separated list of linked resources to include in the response
Response a meta attribute hash containing paging information.
Organizations are returned as an array under the organizations key.
Retrieve a single Organization
GET /api/organizations/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer id of the resource to retrieve
- include (optional, string) ... comma separated list of linked resources to include in the response
- display_name (optional, string)...name filter
- listed (boolean) ... publicly visible
Create a Organization
POST /api/organizations HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"Organizations": {
"display_name": "United Federation of Projects",
"description": "Lots o' Projects",
"primary_language": "en-us",
"links": {
"projects": ["1", "2"]
}
}
}
Requires at least a display_name, description and primary_language*.
Edit a single Organization
PUT /api/organizations/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"organizations": {
"display_name": "Klingon Empire",
"links": {
"workflows": ["1"],
"subject_sets": ["10"]
}
}
}
A User must be the owner of a Organization or have update permissions to edit the resource.
Setting has may links through a PUT, while supported, is not recommended. Instead, use the link endpoints explained below.
Destroy a single Organization
DELETE /api/organizations/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
A user may destroy a Organization they own or have destroy permissions for.
Add Organization Links
POST /api/organizations/123/links/projects HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"projects": ["1", "2"]
}
The body key must match the link_type parameter.
- Parameters
- id (required, integer) - the id of the project to add
- link_type (required, string)
the name of the link to edit
- Members
projects
- Members
Destroy a Link
DELETE /api/organizations/123/links/projects/1,2 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
The recommended way to destroy Organization links. Will destroy the comma separated list of link ids for the given link type.
- Parameters
- id (required, integer) ... the id of the project to modify
- link_type (required, string)
the name of the link to edit
- Members
projects
- Members
- link_ids (required, string) ... comma separated list of ids to destroy
Project Preferences
{
"links": {
"project_preferences.user": {
"href": "/user/{project_preferences.user}",
"type": "users"
},
"project_preferences.project": {
"href": "/projects/{project_preferences.project}",
"type": "projects"
}
},
"meta": {
"project_preferences": {
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/project_preferences?page_size=2",
"previous_href": "/project_preferences?page=14page_size=2",
"next_href": "/project_preferences?page=2&page_size=2",
"last_href": "/project_preferences?page=14&page_size=2"
}
},
"project_preferences": [{
"id": "942",
"email_communication": true,
"preferences": {
"tutorial": true
},
"created_at": "2014-03-20T06:23:12Z",
"updated_at": "2014-04-21T08:22:22Z",
"links": {
"user" : "30",
"project": "11"
}
},{
"id": "949",
"email_communication": true,
"preferences": {
"tutorial": true
},
"created_at": "2014-08-20T06:23:12Z",
"updated_at": "2014-09-21T08:22:22Z",
"links": {
"user" : "33",
"project": "81"
}
}]
}
A Project Preference resource captures a user's settings for a particular project.
It has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
created_at | datetime | read-only |
updated_at | datetime | read-only |
preferences | jsonb | |
email_communication | boolean |
id, created_at, and updated_at are set the by the API. Project preferences are only visible to user they belong to.
List all ProjectPreferences
GET /project_preferences HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
- sort (optional, string) ... field to sort by
- user_id (optional, integer) ... user_id to see preferences for
- project_id (optional, integer) ... project_id to see preferences for
- include (optional, string) ... comma separated list of linked resources to load
Responses will have meta attribute hash containing paging information.
ProjectPreferences are returned as an array under project_preferences.
Retrieve a single ProjectPreference
GET /api/project_preferences/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer identifier of resource
- include (optional, string) ... comma separated list of linked resources to load
Create a ProjectPreference
POST /api/project_preferences HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"project_preferences": {
"email_communication": true,
"preferences": {
"tutorial": true
},
"links": {
"project": "1"
}
}
}
Creating a Project Preference requires only a link to a project. Optionally a boolean flag for email_communication or a hash of settings for preferences may be included.
Since a user can only create, read, or modify their own preferences the currently logged in user is always set as the linked user on creation.
Edit a ProjectPreference
PUT /api/project_preferences/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"project_preferences": {
"preferences": {
"mini_course": false,
}
}
}
Only the owning user may edit a Project Preference resource. The email_communication field and the preferences field may be edited.
Editing the preferences field requires a full representation of the preferences hash to be sent.
Edit ProjectPreferences Settings
POST /api/project_preferencess?user_id=1&project_id=1 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"project_preferences": {
"settings": {
"workflow_id": 1234,
}
}
}
Project owners may edit the settings attribute of any user's Project Preferences associated with that project (and only that project). You need to provide the "user_id" and the "project_id" to specify the resource to apply the settings update to. Note: in the settings payload the "workflow_id" is the only accepted parameter.
- Parameters
- user_id (string) ... The id of the user whose preference needs updating
- project_id (string) ... The id of the project the preference setting should be scoped to
Project Roles
{
"links": {
"project_roles.owner": {
"href": "/{project_roles.owner.href}",
"type": "owners"
},
"project_roles.project": {
"href": "/projects/{project_roles.project}",
"type": "projects"
}
},
"meta": {
"project_roles": {
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/project_roles?page_size=2",
"previous_href": "/project_roles?page=14page_size=2",
"next_href": "/project_roles?page=2&page_size=2",
"last_href": "/project_roles?page=14&page_size=2"
}
},
"project_roles": [{
"id": "942",
"roles": ["collaborator"],
"created_at": "2014-03-20T06:23:12Z",
"updated_at": "2014-04-21T08:22:22Z",
"links": {
"project": "11",
"owner": {
"id": "3",
"display_name": "Owner 3",
"type": "users",
"href": "users/3"
}
}
},{
"id": "949",
"roles": ["tester", "translator"],
"created_at": "2014-08-20T06:23:12Z",
"updated_at": "2014-09-21T08:22:22Z",
"links": {
"project": "81",
"owner": {
"id": "33",
"display_name": "Owner 33",
"type": "users",
"href": "users/33"
}
}
}]
}
A Project Role resources contains an array of roles assigned to a user for a particular project
It has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
roles | array(string) | |
created_at | datetime | read-only |
updated_at | datetime | read-only |
id, created_at, and updated_at are set the by the API. Project roles are visible to the project owner and the user given roles.
- Roles for a project may be:
- collaborator - full access to edit or delete a project
- tester - Able to see a private project
- scientist - Able to moderate project Talk and see a private project
- moderator - Able to moderate project Talk and see a private project
- translator - Able to create new and edit project and workflow translations
List all ProjectRoles
GET /api/project_roles HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
- sort (optional, string) ... field to sort by
- user_id (optional, integer) ... user_id to see roles for
- project_id (optional, integer) ... project_id to see roles for
- include (optional, string) ... comma separate list of linked resources to load
Response will have a meta attribute hash containing paging information.
ProjectRoles are returned as an array under project_roles.
Retrieve a single ProjectRole
GET /api/project_roles/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer identifier of the project role resource
- include (optional, string) ... comma separate list of linked resources to load
Create a ProjectRole
POST /api/project_roles HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"project_roles": {
"roles": ["collaborator"],
"links": {
"project": "11",
"user": "30"
}
}
}
Creating a Project Role resource requires a link to a user and a project. You may also include an array of roles.
Edit a ProjectRole
PUT /api/project_roles/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"project_roles": {
"roles": ["tester", "translator"]
}
}
A user with permissions to edit a project may modify roles for other users in the project. A user without edit permissions may not edit their own roles.
Editing requires sending a full representation of the roles array.
Projects
{
"projects": [{
"id": "1",
"display_name": "Galaxy Zoo",
"classifications_count": "1000000",
"subjects_count": "10000",
"created_at": "2014-03-24T10:42:21Z",
"updated_at": "2014-03-24T10:42:21Z",
"available_languages": ["en"],
"title": "Galaxy Zoo",
"description": "A Project ...",
"guide": [{
"image": "http://something.example.com/delorean.jpg",
"explanation": "our ride"
}],
"team_members": [{
"name": "Doc Brown",
"bio": "",
"twitter": "thatsmydelorean",
"insitution": nil
}],
"science_case": "88mph + 1.21 GW = 1955",
"introduction": "asdfasdf",
"background_image": "http://test.host/12312asd.jp2",
"private": false,
"faq": "This project uses..",
"result": "We found amazing things",
"education_content": "Educator content goes here",
"retired_subjects_count": "5000",
"configuration": { "option_1": "value" },
"beta": "false",
"approved": "true",
"live": "true",
"links": {
"owner": {
"id": "2",
"display_name": "Owner 2",
"href": "/users/2",
"type": "user"
}
}
}],
"links": {
"projects.subjects": {
"href": "/subjects?project_id={projects.id}",
"type": "subjects"
},
"projects.classifications": {
"href": "/classifications?project_id={projects.id}",
"type": "classifications"
},
"projects.workflows": {
"href": "/workflows?project_id={projects.id}",
"type": "workflows"
},
"projects.subject_sets": {
"href": "/subject_sets/{projects.subject_sets}",
"type": "subject_sets"
},
"projects.owner": {
"href": "/{projects.owner.href}",
"type": "owners"
}
}
}
A Project is a collection of subjects and task workflows that a volunteer performs on subjects. The project also holds supplementary text describing the tasks volunteers perform.
It has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
display_name | string | |
classifications_count | integer | read-only |
subjects_count | integer | read-only |
created_at | string | read-only |
updated_at | string | read-only |
available_languages | array(string) | |
title | string | |
description | string | |
guide | array(hash) | |
team_members | array(hash) | |
science_case | string | |
introduction | string | |
avatar | ?? | |
background_image | string | |
private | boolean | |
faq | string | |
result | string | |
education_content | string | |
retired_subjects_count | integer | read-only |
configuration | hash | |
beta | boolean | |
approved | boolean | |
live | boolean |
id, created_at, updated_at, user_count, and classifications_count are set by the API.
Project Links
workflows
subject_sets
- If you add a link to a subject set that does not already belong to the project, Panoptes will make a duplicate of that subject set in this project. Note that you can only link subject sets of other projects that you are a collaborator on.- subjects (read-only)
- classifications (read-only)
- owner (read-only)
List All Projects
GET /api/projects HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- display_name (string) ... project name filter
- approved (boolean) ... approved state filter
- beta (boolean) ... beta state filter
- live (boolean) ... live state filter
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
- sort (optional, string) ... field to sort by
- owner (optional, string) ... string owner name of either a user or a user group to filter by.
- include (optional, string) ... comma separated list of linked resources to include in the response
Retrieve a single Project
GET /api/projects/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer id of the resource to retrieve
- display_name (string) ... project name filter
- approved (boolean) ... approved state filter
- beta (boolean) ... beta state filter
- live (boolean) ... live state filter
Create a Project
POST /api/projects HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"projects": {
"name": "galaxy_zoo",
"description": "A doubleplus good project",
"primary_language": "en-us",
"private": true,
"links": {
"workflows": ["1", "2"]
"owner": {
"id": 10,
"display_name": "Owner 2",
"type": "user_groups",
"href": "user_groups/10"
}
}
}
}
Requires at least a display_name, description, primary_language and private. Workflows and SubjectSets added as links will be copied and their new ids returned.
Edit a single Project
PUT /api/projects/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"projects": {
"display_name": "Galaxy Zooooooooo!",
"links": {
"workflows": ["1"],
"subject_sets": ["10"]
}
}
}
A User must be the owner of a project or have update permissions to edit the resource. Workflow and Subject Set links may be edited. Removing a subject set or workflow causes the subject set or workflow to be destroyed. Adding a workflow or subject set causes the original to be copied and a new id to be returned.
Setting has may links through a PUT, while supported, is not recommended. Instead, use the link endpoints explained below.
Destroy a single Project
DELETE /api/projects/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
A user may destroy a project they own or have destroy permissions for.
Response will be an HTTP 204.
SubjectSetImports
Feature Description
This resource is useful when a researcher has a large batch to add. The upload process goes as follows:
- A researcher uploads image files into a web accessible location (e.g. s3 bucket, azure blob store, etc).
- She also creates a manifest file (format described below) and uploads the manifest to a web accessible location.
- The manifest file describes 'subjects', which is the Zooniverse term for something that is to be classified.
- A subject is made up of:
- a unique external ID (used to track the subject from your organization)
- one or more URLs that host media files e.g. image, video, audio.
- metadata described as key-value pairs.
- The researcher will then send the manifest payload to the Zooniverse API programatically
- Python example of how to send a manifest
- The repsonse to this manifest upload will be a
SubjectSetImport
API resource.
- This calls the Zooniverse API which enqueues a background job on the Zooniverse servers.
- In the background, the Zooniverse's systems process the downloaded manifest file, creating subjects in the specified subject set.
- The
SubjectSetImport
resource API end point response can be polled for information on the progress and state of an import (see python example above or 'Retrieve a single import' below).
Zooniverse API Feature Description
Creating a new subject set import
POST /api/subject_set_imports HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"subject_set_imports": {
"source_url": "https://path.to/some/manifest.csv",
"links": {
"subject_set": "1"
}
}
}
Returns a SubjectSetImport resource with an ID. This resource can be polled in order to get the status of the import.
Retrieve a single import
GET /api/subject_set_imports/1 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer id of the resource to retrieve
Manifest CSV format
external_id,location:1,location:2,metadata:size,metadata:cuteness
1,https://placekitten.com/200/300.jpg,https://placekitten.com/200/100.jpg,small,cute
2,https://placekitten.com/400/900.jpg,https://placekitten.com/500/100.jpg,large,cute
The manifest.csv file is contains one row per subject. See the example to the right. It is expected to have the following columns:
external_id
- Zooniverse uses this to deduplicate/upsert existing subjects, so that it's possible to reimport a manifest into a subject set.location:
- One or more columns that begin withlocation:
(including the colon), followed by any sequence of characters. The values of cells in this column are URLs pointing to the uploaded image files in the S3 bucket. Multiple "location:" columns are supported (obviously the value after the colon needs to be unique, but is otherwise ignored). Supported mimetypes currently are:- image/jpeg
- image/png
- image/gif
- image/svg+xml
- audio/mpeg
- audio/mp3
- audio/mp4
- audio/x-m4a
- video/* (Depends on browser support)
- text/plain
metadata:
- Zero or more columns that begin withmetadata:
(including the colon), followed by the key of the specific metadata in this column.
SetMemberSubjects
{
"links": {
"set_member_subjects.subject": {
"href": "/subjects/{set_member_subjects.subject}",
"type": "subjects"
},
"set_member_subjects.subject_set": {
"href": "/subject_sets/{set_member_subjects.subject_set}",
"type": "subject_sets"
}
},
"meta": {
"set_member_subjects": {
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/set_member_subjects?page_size=2",
"previous_href": "/set_member_subjects?page=14page_size=2",
"next_href": "/set_member_subjects?page=2&page_size=2",
"last_href": "/set_member_subjects?page=14&page_size=2"
}
},
"set_member_subjects": [{
"id": "1023",
"created_at": "2014-03-20T00:15:47Z",
"updated_at": "2013-09-30T10:20:32Z",
"state": "active",
"priority": 101231.1231,
"links": {
"subject": "1231",
"subject_set": "101"
}
},{
"id": "1024",
"created_at": "2014-03-20T00:15:47Z",
"updated_at": "2013-09-30T10:20:32Z",
"state": "retired",
"priority": 1231.1231,
"links": {
"subject": "1232",
"subject_set": "101"
}
}]
}
A Set Member Subject resource contains the state of a subject that is included in a resource.
It has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
state | string | |
priority | float | |
created_at | datetime | read-only |
updated_at | datetime | read-only |
id, created_at, and updated_at are set by the API server.
List all SetMemberSubjects
GET /api/set_member_subjects HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
- subject_id (optional, integer) ... id of subject to see set_member_subjects for
- subject_set_id (optional, integer) ... id of subject_set to see set_member_subjects for
- include (optional, string) ... comma separated list of linked resources to load
Response will contain a meta attribute hash containing paging information.
SetMemberSubjects are returned as an array under set_member_subjects.
Retrieve a Single SetMemberSubject
GET /api/set_member_subjects/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer identifier for the resource
- include (optional, string) ... comma separated list of linked resources to load
Create a SetMemberSubject
POST /api/set_member_subjects HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"set_member_subjects: {
"links": {
"subject": "12031",
"subject_set": "10"
}
}
}
A SetMemberSubject may be created by a user that can see the Subject they wish to link to and can edit the project the SubjectSet belongs to.
A SetMemberSubject requires links be provided to a Subject and a SubjectSet. Optionally, the create request may include a state and a priority. The state will be 'active' by default and the priority will be null by default.
Edit a SetMemberSubject
PUT /api/set_member_subjects/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"set_member_subjects: {
"state": "inactive"
}
}
A user with edit permissions for the project a SetMemberSubject's SubjectSet belongs to may edit the state and priority attributes.
Destroy a SetMemberSubject
DELETE /api/set_member_subjects/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
A user with edit permissions for the project a SetMemberSubject's Subject belongs to may destroy a SetMemberSubject resource. This removes the linked Subject form the linked SubjectSet
SubjectSets
{
"links": {
"subject_sets.workflows": {
"href": "/workflows?subject_set_id={subject_sets.id}",
"type": "workflows"
},
"subject_sets.subjects": {
"href": "/subjects{?subject_set_id=subject_sets.id}",
"type": "subjects"
},
"subject_sets.set_member_subjects": {
"href": "/set_member_subjects{?subject_set_id=subject_sets.id}",
"type": "set_member_subjects"
},
"subject_sets.project": {
"href": "/project/{subject_sets.project}",
"type": "projects"
}
},
"meta": {
"subject_sets": {
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/subject_sets?page_size=2",
"previous_href": "/subject_sets?page=14page_size=2",
"next_href": "/subject_sets?page=2&page_size=2",
"last_href": "/subject_sets?page=14&page_size=2"
}
},
"subject_sets": [{
"id": "20",
"display_name": "Weird Looking Galaxies",
"metadata": {
"category": "things"
},
"created_at": "2014-02-13T10:11:34Z",
"updated_at": "2014-02-13T10:11:34Z",
"set_member_subject_count": 100,
"links": {
"project": "1",
"workflow": "10"
}
},{
"id": "20",
"display_name": "Boring Looking Galaxies",
"metadata": {
"category": "things"
},
"created_at": "2014-02-13T10:11:34Z",
"updated_at": "2014-02-13T10:11:34Z",
"set_member_subject_count": 100,
"links": {
"project": "1",
"workflow": "11"
}
}]
}
Subject Sets represent collections of Subjects that are paired with a workflow of questions to be answered. A SubjectSet belongs to one Workflow, while a single Workflow may have many SubjectSets.
A SubjectSet has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
display_name | string | |
metadata | jsonb | |
set_member_subjects_count | integer | |
created_at | datetime | read-only |
updated_at | datetime | read-only |
All attributes except display_name are set by the API
List all Subject Sets
GET /api/subject_sets HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... index of the page to retrieve 1 by default
- page_size (optional, integer) ... number of items per page 20 by default
- sort (optional, string) ... field to sort by, id by default
- project_id (optional, integer) ... filter by linked project
- workflow_id (optional, integer) ... filter by linked workflow
- include (optional, string) ... comma separated list of linked resources to include in the response
Response contains a meta attribute hash containing paging information.
Subject Sets are returned as an array under subject_sets.
Retrieve a single Subject Set
GET /api/subject_sets/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer id of the subject_set to retrieve
- include (optional, string) ... comma separated list of linked resources to include in the response
Create a Subject Set
POST /api/subject_sets HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"subject_sets": {
"display_name": "A Group of Interesting Subjects",
"metadata": {
"category": "things"
},
"links": {
"project": "43",
"workflows": ["47"],
"subjects": ["234", "1243", "8023"]
}
}
}
A subject set must supply a display_name and a link to a project. Optionally, it may include links to subjects and a single workflow.
Instead of a list of subjects a SubjectSet may include a link to a Collection which will import the collection's subjects into a new SubjectSet.
Edit a single Subject Set
PUT /api/subject_sets/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"subject_sets": {
"display_name": "Normal Galaxies",
"links": {
"subjects": ["1", "2", "4", "5", "10"]
}
}
}
A user may only edit a subject if they edit permissions for the parent project. The display_name attributes and links to workflows and subjects are editable. Editing links requires a full representation of the new set of links, but does not destroy unlinked resources.
This is NOT the recommended way to manage linked subjects.
Destroy a Subject Set
DELETE /api/subject_sets/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
A user may only destroy a subject set if they have destroy permissions for the subject set's project.
Subject Set Links
Allows the addition of links to subjects to a subject set object without needing to send a full representation of the linked relationship.
This is the recommended way to managed linked subjects.
Add Subject Set Link
POST /api/subject_sets/123/links/subjects HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"subjects": ["1", "5", "9", "11"]
}
- Parameters
- id (required, integer) ... the id of the Subject Set to modify
- link_type (required, string) ... the relationship to modify must be the same as the supplied body key Only Subjects links may be edited.
Destroy Subject Set Links
DELETE /api/subject_sets/123/links/subjects/1,2,3 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
Allows links to be removed without sending a full representation of the linked relationship.
- Parameters
- id (required, integer) ... the id of the Subject Set to modify
- link_type (required, string) ... the relationship to modify
- link_ids (required, integer) ... comma separated list of ids to remove
Will only remove the link. This operation does not destroy the linked object.
SubjectWorkflowStatuses
{
"links": {
"SubjectWorkflowStatuses.workflow": {
"href": "/workflows/{subject_workflow_statuses.workflow}",
"type": "workflows"
},
"SubjectWorkflowStatus.subject": {
"href": "/subjects/{subject_workflow_statuses.subject}",
"type": "subjects"
}
},
"meta": {
"collection_preferences": {
"page": 1,
"page_size": 2,
"count": 2,
"include": [],
"page_count": 1,
"previous_page": 0,
"next_page": 0,
"first_href": "/subject_workflow_statuses?page_size=2",
"previous_href": "",
"next_href": "",
"last_href": "/subject_workflow_statuses?page=2&page_size=2"
}
},
"subject_workflow_statuses": [{
"id": "1",
"created_at": "2014-03-20T06:23:12Z",
"updated_at": "2014-04-21T08:22:22Z",
"classifications_count": 10,
"retired_at": "2014-04-21T08:22:22Z",
"retirement_reason": "consensus",
"links": {
"workflow" : "3",
"subject": "4"
}
},{
"id": "2",
"created_at": "2014-03-21T06:23:12Z",
"updated_at": "2014-04-22T08:22:22Z",
"classifications_count": 2,
"retired_at": "2014-04-22T08:22:22Z",
"retirement_reason": "blank",
"links": {
"workflow" : "3",
"subject": "5"
}
}]
}
A SubjectWorkflowStatus resource collates the status of a subject in a workflow. This status includes the classification count and the retirement state and reason.
It has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
classifications_count | integer | |
retired_at | datetime | |
retirement_reason | string | |
created_at | datetime | read-only |
updated_at | datetime | read-only |
id, created_at, and updated_at are set the by the API.
SubjectWorkflowStatuses are only visible to users with rights on the workflow's associated project.
List all SubjectWorkflowStatuses
GET /api/subject_workflow_statuses HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
- workflow_id (optional, integer) ... workflow to see SubjectWorkflowStatuses for
- subject_id (optional, integer) ... subject_id to see SubjectWorkflowStatuses for
- include (optional, string) ... comma separated list of linked resources to load
Response will have a meta attribute hash containing paging information.
SubjectWorkflowStatuses are returned as an array under subject_workflow_statuses.
Retrieve a single SubjectWorkflowStatus
GET /api/subject_workflow_statuses/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer identifier of resource
- include (optional, string) ... comma separated list of linked resources to load
Subjects
{
"links": {
"subjects.project": {
"href": "/projects/subjects.project",
"type": "projects"
},
"subjects.subject_sets": {
"href": "/subject_sets/subjects.subject_sets",
"type": "subject_sets"
}
},
"meta": {
"subjects": {
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/subjects?page_size=2",
"previous_href": "/subjects?page=14page_size=2",
"next_href": "/subjects?page=2&page_size=2",
"last_href": "/subjects?page=14&page_size=2"
}
},
"subjects": [{
"id": "1",
"zooniverse_id": "AGFS0001231",
"created_at": "2014-03-24T10:42:21Z",
"updated_at": "2014-03-24T10:42:21Z",
"locations": [
{"image/jpeg": "http://s3.amazonaws.com/subjects/1.png"}
],
"metadata": {
"lens_type": "50mm"
},
"links": {
"project": "1"
"subject_sets": ["1"]
}
},{
"id": "2",
"zooniverse_id": "AGFS0001232",
"created_at": "2014-03-24T10:44:21Z",
"updated_at": "2014-03-24T10:44:21Z",
"locations": [
{"image/jpeg": "http://s3.amazonaws.com/subjects/2.png"}
],
"metadata": {
"lens_type": "50mm"
},
"links": {
"project": "1"
"subject_sets": ["1"]
}
}]
}
A single Subject object. A Subject is a resource that describe a piece of media to be classified including metadata about the object.
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
zooniverse_id | integer | read-only |
locations | array(hash) | |
metadata | hash | |
created_at | datetime | read-only |
updated_at | datetime | read-only |
id, zooniverse_id, created_at, and updated_at are assigned by the API.
List Subjects
GET /api/subjects HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
- sort (optional, string) ... field to sort by
- workflow_id (optional, integer) ... filter to subjects belonging to a specific workflow
- subject_set_id (optional, integer) ... return subjects belonging to the identified subject_set
Response will have a meta attribute hash containing paging information.
Subjects are returned as an array under the subjects key.
Retrieve a single Subject
GET /api/subjects/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer id of the subject resource
Create a Subject
POST /api/subjects HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"subjects": {
"locations": [
"image/png",
[
"video/webm",
"video/mp4"
]
],
"metadata": {
"lens_type": "50mm"
},
"links": {
"project": "1"
}
}
}
A locations attribute and a project link are required.
To have the Zooniverse host your media resources the locations array
should have the mime-types of the subject's associated media,
e.g "locations":["image/png", "image/jpeg", "image/png"]
,
note the locations mime types are stored in order.
The create response will contain signed s3 urls the client may make a PUT request containing the media to. The signed urls will be valid for 20 minutes. Please take the order of the returned s3 urls into account when PUT'ing local media resources to the remote location.
To use your own hosted media resources the locations array
should be comprised of objects that represent the mime-type and the hosted URL
of the subject's associated media,
e.g. "locations":[
{"image/png": "https://your.s3_account.com/subjects/1.png"},
{"image/jpeg": "https://your.s3_account.com/subjects/1.jpg"}
]
.
The metadata attribute is optional.
Edit a single Subject
PUT /api/subjects/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"subjects": {
"locations": [
"image/png"
]
}
}
Users are permitted to edit subjects belonging to projects a user has edit permissions for. A user may not change the project of a subject.
The locations array should have the mime-types of the subject's associated media. The response will contain signed s3 urls the client may make a PUT request containing the media to. The signed urls will be valid for 20 minutes.
A request changing the metadata hash must contain a full representation of the attribute.
Destroy a single subject
DELETE /api/subjects/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
Users are permitted to destroy a subjects they own or subjects belongs to a project a user has destroy permissions for.
Subject Versions
{
"meta": {
"versions": {
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/subjects/101/versions?page_size=2",
"previous_href": "/subjects/101/versions?page=14page_size=2",
"next_href": "/subjects/101/versions/?page=2&page_size=2",
"last_href": "/subjects/101/versions?page=14&page_size=2"
}
},
"versions": [{
"id": "42",
"changeset": {
"metadata": [{
"ra": "120.2",
"dec": "-12.4"
},{
"ra": "121.1",
"dec": "-11.1"
}]
},
"whodunnit": "stuartlynn",
"created_at": "2014-03-20T06:23:12Z",
"links": {
"item": {
"id": "101",
"href": "/subject/101",
"type": "subjects"
}
}
},{
"id": "43",
"changeset": {
"metadata": [{
"ra": "20.2",
"dec": "12.4"
},{
"ra": "21.1",
"dec": "11.1"
}]
},
"whodunnit": "stuartlynn",
"created_at": "2014-03-20T06:23:12Z",
"links": {
"item": {
"id": "101",
"href": "/subject/101",
"type": "subjects"
}
}
}]
}
A Subject Version resource represents a set of changes made to a Subject resource.
It has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
changeset | jsonb | read-only |
whodunnit | string | read-only |
created_at | datetime | read-only |
It is NOT editable.
List all Subject Versions
GET /api/subjects/123/versions HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- subject_id (required, integer) ... id of the subject to retreive versions for
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
Response will have a meta attribute hash containing paging information.
Subject Versions are returned as an array under versions.
Retrieve a Single Subject Version
GET /api/subjects/123/versions/2 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- subject_id (required, integer) ... id of the subject to retreive versions for
- id (required, integer) ... integer id of the version to load
Retrieve subjects to classify
GET /api/v1/subjects/queued HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
While the normal GET on the subjects resource will return a list of subjects in a project, there is a special API for getting some subjects that need classifications: GET /api/v1/subjects/queued
. This special API is optimized specifically for serving a selection of subjects that should be shown to the user in the classify interface.
- Parameters
- workflow_id (required, integer) ... filter to subjects belonging to a specific workflow
- subject_set_id (optional, integer) ... return subjects belonging to the identified subject_set, it is required when the workflow is grouped.
UserGroups
{
"links": {
"user_groups.projects": {
"href": "/projects?owner={user_groups.owner_name}",
"type": "projects"
},
"user_groups.classifications": {
"href": "/classifications?user_group_id={user_groups.id}",
"type": "classifications"
},
"user_groups.collections": {
"href": "/collections?owner={user_groups.owner_name}"
"type": "collections"
},
"user_groups.users": {
"href": "/users?user_group_id={user_groups.id}",
"type": "users"
},
"user_groups.memberships": {
"href": "/memberships?user_group_id={user_groups.id}",
"type": "memberships"
}
},
"meta": {
"user_groups": {
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/user_groups?page_size=2",
"previous_href": "/user_groups?page=14page_size=2",
"next_href": "/user_groups?page=2&page_size=2",
"last_href": "/user_groups?page=14&page_size=2"
}
},
"user_groups": [{
"id": "42",
"name": "a_cool_group",
"display_name": "A Cool Group",
"owner_name": "a_cool_group",
"created_at": "2014-08-11T10:11:34Z",
"updated_at": "2014-12-11T00:11:34Z",
"classifications_count": "1002340",
"activated_state": "active",
"stats_visibility": "private_agg_only",
"links": {
"memberships": ["101", "102"],
"users": ["10001", "9102"],
"projects": ["10"],
"collections": ["11"]
}
},{
"id": "44",
"name": "a_cool_gang",
"display_name": "A Cool Gang",
"owner_name": "a_cool_gang",
"created_at": "2014-09-10T10:41:54Z",
"updated_at": "2014-11-11T01:21:33Z",
"classifications_count": "2341",
"activated_state": "active",
"stats_visibility": "public_show_all",
"links": {
"memberships": ["101", "102"],
"users": ["10001", "9102"],
"projects": ["10"],
"collections": ["11"]
}
}]
}
A user group represents a collection of users that share ownership of projects, collections, and classifications. Individual users within the group can be given different levels of permissions to act on group owned resources.
A User Group has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
classifications_count | integer | |
activated_state | string | |
name | string | |
display_name | string | |
stats_visibility | string | |
created_at | datetime | read-only |
updated_at | datetime | read-only |
id, created_at, updated_at, and classifications_count are all set by the API.
Stats Visibility Levels
We have added Stats Visibility Levels for new stats features on User Groups. The stats_visibility
is an enum type on the user_group
model on Panoptes.
Currently there are 5 Levels of Visibility.
Stats Visibility Levels (Matching number with its corresponding numeric in Panoptes):
0) private_agg_only
(DEFAULT) : Only members of a user group can view aggregate stats. Individual stats are ONLY viewable by ADMINS of the user group.
1) private_show_agg_and_ind
: Only members of a user group can view aggregate stats. Individual stats is viewable by BOTH members and admins of the user group.
2) public_agg_only
: Anyone can view aggregate stats of the user group. Only ADMINS of the user group can view individual stats.
3) public_agg_show_ind_if_member
: Anyone can view aggregate stats of the user group. Both members and admins of the user group can view individual stats.
4) public_show_all
: Anyone can view aggregate stats of the user group and can view individual stats of the user group. Authentication/Authorization to view user_group stats is NOT needed.
List all User Groups
GET /api/user_groups HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... index of the page to retrieve 1 by default
- page_size (optional, integer) ... number of items per page 20 by default
- sort (optional, string) ... field to sort by, id by default
- user_id (optional, integer) ... filter list to groups a user is part of
- include (optional, string) ... comma separated list of linked resources to include in the response
Response has a meta attribute hash containing paging information.
User Groups are returned as an array under user_groups.
Retrieve a single User Group
GET /api/user_groups/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... integer, id of the user group
- include (optional, string) ... comma separated list of linked resources to include in the response
Create a User Group
POST /api/user_groups HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"user_groups": {
"display_name": "A Super Grouper!",
"links": {
"users": ["10", "22"]
}
}
}
A user can create new group by just giving it a name (how it appears in a @mention and url) or display name (how it shown to other users).
In the case where only a display name is provided, the name will be set to the underscored, downcased, and url escaped version of the display name. When only a name is provided, display_name will be set to the same string as name.
Optionally links to other users who will be given memberships with the 'invited' state.
Edit a single User Group
PUT /api/user_groups/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"user_groups": {
"display_name": "A Uncool Group",
"links": {
"projects": [],
"collections": []
}
}
}
A user with edit permissions on a user group may edit the group's name, display_name, or links to projects, collections and users. Projects and Collections may only be removed. Removing a link to a project or collection will destroy the project or collection, removing a link to a user will set their membership state to inactive.
Adding a user creates a membership link with an 'invited' state. Membership and Classification links cannot be modified.
This is NOT the recommended way to modify links.
Destroy a User Group
DELETE /api/user_groups/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
A user may destroy a group if they have the requisite permissions. A destroyed group and linked projects, collections, and memberships will be placed in an 'inactive' state.
Add user links
POST /user_groups/123/links/users HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"users": ["123", "23"]
}
Only links to users may be added. Creates a membership for a user. The membership will be immediately added, but a user won't show up in the group's links until they set their membership to 'active'. Only links to users may be added.
Remove links
DELETE /user_groups/123/links/users/1,2,3 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... id of the group to be edited.
- link_type (required, string) ... name of the link to modify
- link_ids (required, string) ... comma separated list of ids to remove
Allows links to users, projects, or collections to be removed. Removed projects and collections are deleted. Removed users have their membership set to 'inactive'.
Users
{
"users": [{
"id": 1,
"created_at": "2014-03-20T00:15:47Z",
"updated_at": "2013-09-30T10:20:32Z",
"credited_name": "Dr. Stuart Lynn",
"login": "stuart",
"display_name": "Stuart",
"owner_name": "stuart",
"email": "stuart@zoooniverse.org",
"zooniverse_id": "123432",
"classifications_count": "104",
"languages": ["en-gb", "es-mx"]
}],
"links": {
"users.projects": {
"href": "/projects?owner={users.owner_name}",
"type": "projects"
},
"users.user_groups": {
"href": "/user_groups?user_id={users.id}",
"type": "user_groups"
},
"users.subjects": {
"href": "/subjects?user_id={users.id}",
"type": "subjects"
},
"users.collections": {
"href": "/collections?owner={users.owner_name}",
"type": "collections"
}
}
}
A User is representation of the identity and contributions of a volunteer.
Attribute | Type | Description |
---|---|---|
id | Integer | |
created_at | string | |
updated_at | string | |
credited_name | string | Publicly available name with which a volunteer will be credited on papers, posters, etc |
login | string | |
display_name | string | |
string | The email of the user | |
zooniverse_id | string | |
classifications_count | integer | Number of classifications this user has made site-wide |
languages | Array(String) | Array of language identifier string, in order from most to least preferred. Used to determine which language to show translated projects in. |
id
, zooniverse_id
, created_at
, updated_at
, and classification_count
are created and updated by the Panoptes API.
credited_name
is the publicly available name with which a volunteer will be
credited on papers, posters, etc. When serialized, if an @
character is
found, the user's login will be returned instead for privacy reasons.
The email
attribute is only available if the requesting user is an
administrator or the user resource being requested is that of the requesting
user.
User Links
- projects
- user_groups
- subjects
- collections
List Users
GET /api/users HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
Parameters:
- page (optional, integer) ... index of the collection page, 1 is default
- page_size (optional, integer) ... number of items on a page. 20 is default
- sort (optional, string) ... fields to sort collection by. id is default
- include (optional, string) ... comma separated list of linked resources to include
Retrieve a single user
GET /api/users/1 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
Parameter | Type | Default | Description |
---|---|---|---|
id | integer | ID of the User as an integer key |
Edit a single User
PUT /api/users/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"users": {
"credited_name": "Dr. Stuart Lynn, DDS"
}
}
The currently logged in User may edit their record by sending a partial representation of the resource including their changes. A User cannot edit linked resources.
Destroy a single User
DELETE /users/123 HTTP/1.1
The current logged in User may delete themself. This does not fully remove the user resource; instead, it deactivates their projects and removes personally identifying information including the credited_name and email address.
- Response 204
Workflows
{
"links": {
"workflows.subjects": {
"href": "/subjects{?workflow_id=workflows.id}",
"type": "subjects"
},
"workflows.project": {
"href": "/projects/{workflows.project}",
"type": "projects"
},
"workflows.subject_sets": {
"href": "/subject_sets?workflow_id={workflows.id}",
"type": "subject_sets"
}
},
"meta": {
"workflows": {
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/workflows?page_size=2",
"previous_href": "/workflows?page=14page_size=2",
"next_href": "/workflows?page=2&page_size=2",
"last_href": "/workflows?page=14&page_size=2"
}
},
"workflows": [{
"id": "22",
"display_name": "Find moons",
"created_at": "2014-02-13T10:11:34Z",
"updated_at": "2014-02-13T10:11:34Z",
"classifications_count": 1000,
"pairwise": false,
"grouped" : false,
"prioritized": false,
"primary_language": "es_MX",
"workflow_version": "22.1",
"content_language": "en_US",
"first_task": "interest",
"tasks": {
"interest": {
"type": "drawing",
"question": "Color some points",
"tools": [
{"value": "red", "label": "Red", "type": "point", "color": "red"},
{"value": "green", "label": "Green", "type": "point", "color": "lime"},
{"value": "blue", "label": "Blue", "type": "point", "color": "blue"}
],
"next": "shape"
},
"shape": {
"type": "multiple",
"question": "What shape is this galaxy?",
"answers": [
{"value": "smooth", "label": "Smooth"},
{"value": "features", "label": "Features"},
{"value": "other", "label": "Star or artifact"}
],
"required": true,
"next": "roundness"
},
"roundness": {
"type": "single",
"question": "How round is it?",
"answers": [
{"value": "very", "label": "Very...", "next": "shape"},
{"value": "sorta", "label": "In between"},
{"value": "not", "label": "Cigar shaped"}
],
"next": null
}
},
"links": {
"project": "1",
"subject_sets": ["10", "11", "12"]
}
},{
"id": "23",
"display_name": "Find moons",
"created_at": "2014-02-13T10:11:34Z",
"updated_at": "2014-02-13T10:11:34Z",
"classifications_count": 1000,
"pairwise": false,
"grouped" : false,
"prioritized": false,
"primary_language": "es_MX",
"workflow_version": "22.1",
"content_language": "en_US",
"first_task": "interest",
"tasks": {
"interest": {
"type": "drawing",
"question": "Color some points",
"tools": [
{"value": "red", "label": "Red", "type": "point", "color": "red"},
{"value": "green", "label": "Green", "type": "point", "color": "lime"},
{"value": "blue", "label": "Blue", "type": "point", "color": "blue"}
],
"next": "shape"
},
"shape": {
"type": "multiple",
"question": "What shape is this galaxy?",
"answers": [
{"value": "smooth", "label": "Smooth"},
{"value": "features", "label": "Features"},
{"value": "other", "label": "Star or artifact"}
],
"required": true,
"next": "roundness"
},
"roundness": {
"type": "single",
"question": "How round is it?",
"answers": [
{"value": "very", "label": "Very...", "next": "shape"},
{"value": "sorta", "label": "In between"},
{"value": "not", "label": "Cigar shaped"}
],
"next": null
}
},
"links": {
"project": "1",
"subject_sets": ["10", "11", "12"]
}
}]
}
Workflows represent the series of questions/tasks a user will be asked to complete for a subject. Subjects are selected from SubjectSets. A Workflow may have many SubjectSets linked to, but a SubjectSet may only be linked to a single Workflow.
A workflow has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
display_name | string | |
finished_at | datetime | |
tasks | jsonb | |
classifications_count | integer | |
pairwise | boolean | |
grouped | boolean | |
prioritized | boolean | |
retirement | jsonb | |
retired_set_member_subjects_count | integer | |
active | boolean | |
aggregation | jsonb | |
configuration | jsonb | |
completeness | decimal | |
primary_language | string | |
workflow_version | string | |
content_language | string | |
created_at | datetime | read-only |
updated_at | datetime | read-only |
id, created_at, updated_at, workflow_version, content_language, and classifications_count are assigned by the API
finished_at is set by the API to a date/time when all subjects for this workflow have been retired.
Three parameters: grouped, prioritized, and pairwise configure how the api chooses subjects for classification. They are all false by default, which will give a random selection of subjects from all subject_sets that are part of a workflow. grouped enables selecting subjects from a specific subject set. prioritized ensures that users will see subjects in a predetermined order. pairwise will select two subjects at a tim for classification.
A workflow's tasks
is a hash of keys to task definitions.
A workflow's first_task
is a string matching the key of its first task. (The order of keys in JSON hashes is not guaranteed).
Each task has a type
string of "single" or "multiple" choice, or "drawing". (More task types to come, e.g. Serengeti-style filter and Sunspotter's comparison.)
"multiple" and "drawing" tasks have a next
string, linking to the next task in the workflow. If this string is empty, the workflow ends. In "single" tasks, each answer has a next
string, allowing branching based on the user's decisions.
"single" and "multiple" tasks have a question
string, which the user must answer. Answers to the question are in an answers
array. Each answer has a label
string displayed to the user.
"single" and "multiple" tasks may define a boolean required
, which when true will force the user to provide an answer before moving on to the next task.
"drawing" tasks have an instruction
string telling the user how to complete the task.
"drawing" tasks have a tools
array.
Each tool has a label
shown to the user.
Each tool has a string type
. Options include:
- point
- ellipse
- circle
- line
- rectangle
- polygon
Each tool has a string color
, which is applied to the marks made by the tool. Any format valid as CSS can be used.
List All Workflows
GET /api/workflows HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
- sort (optional, string) ... field to sort by id by default
- project_id (optional, integer) ... filter workflows by project id
- include (optional, string) ... comma separated list of linked resources to load
Response has a meta attribute hash containing paging information.
Workflows are returned as an array under the workflows key.
Retrieve a single Workflow
GET /api/workflows/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- id (required, integer) ... id of the workflow
- include (optional, string) ... comma separated list of linked resources to include in the response
Create a Workflow
POST /api/workflows HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"workflows": {
"display_name": "Spot Monsters!",
"tasks": {
"interest": {
"type": "drawing",
"question": "Color some points",
"tools": [
{"value": "red", "label": "Red", "type": "point", "color": "red"},
{"value": "green", "label": "Green", "type": "point", "color": "lime"},
{"value": "blue", "label": "Blue", "type": "point", "color": "blue"}
],
"next": "shape"
},
"shape": {
"type": "multiple",
"question": "What shape is this galaxy?",
"answers": [
{"value": "smooth", "label": "Smooth"},
{"value": "features", "label": "Features"},
{"value": "other", "label": "Star or artifact"}
],
"required": true,
"next": "roundness"
},
"roundness": {
"type": "single",
"question": "How round is it?",
"answers": [
{"value": "very", "label": "Very...", "next": "shape"},
{"value": "sorta", "label": "In between"},
{"value": "not", "label": "Cigar shaped"}
],
"next": null
}
},
"retirement": {
"criteria": "classification_count",
"options": {
"count": 15
}
},
"primary_language": "en-ca",
"links": {
"project": "42",
"subject_sets": ["1", "2"]
}
}
}
Requires a set of tasks, a primary_language, a display_name, and a link to a project. Can optionally set cellect parameters grouped, prioritized, and pairwise (all false by default) and links to subject_sets.
A SubjectSet that already belongs to another workflow will be duplicated when it is linked.
A Workflow may also include a retirement object with a criteria
key and an options key. criteria describes the strategy Panoptes
will use to decide when to retire subjects while options configures
the strategy. There are 2 valid criteria:
1. classification_count
will retire subjects after a target number
of classifications are reached. You must supply an options
hash
with an integer count
to specify the minimum number of classifications.
+ {"criteria": "classification_count", "options": {"count": 15} }
2. never_retire
will never retire subjects and requires an empty
options
hash.
+ {"criteria": "never_retire "options": {} }
If retirement is left blank Panoptes defaults to the classification_count
strategy with 15 classifications per subject.
Edit a single workflow
PUT /api/workflows/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{
"workflows": {
"tasks": { "format": "all new!"},
"links": {
"subject_sets": ["8"]
}
}
}
A user may edit a workflow if they have edit permissions for the parent project. Editing tasks content requires a full replacement for the field. Only the subject set link may be edited. Removing a subject_set link doesn't destroy the subject_set.
This is not the recommended way to edit links. Use the subject_set link mode documented below.
Destroy a single workflow
DELETE /api/workflows/123 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
A user may destroy a workflow if they have destroy permissions for the parent project.
Link Subject Set to Workflow
POST /api/workflows/123/links/subject_sets HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
{ "subject_sets": ["9"] }
The recommended way to update links.
Adds the posted subject sets to a workflow's links. Creates a copy of the subject set if it belongs do a different project.
- Parameters
- id (required, integer) ... id of workflow to update
Destroy Workflow's Subject Set Links
DELETE /api/workflows/123/links/subject_sets/1,2,3 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
The recommended way to remove links.
Removes workflow's links to the given subject_sets. It does not destroy the subject set models.
- Parameters
- id (required, integer) ... id of workflow to update
- subject_set_ids (required, string) ... comma separated list of ids to destroy
Workflow Versions
{
"meta": {
"versions": {
"page": 1,
"page_size": 2,
"count": 28,
"include": [],
"page_count": 14,
"previous_page": 14,
"next_page": 2,
"first_href": "/workflows/101/versions?page_size=2",
"previous_href": "/workflows/101/versions?page=14page_size=2",
"next_href": "/workflows/101/versions/?page=2&page_size=2",
"last_href": "/workflows/101/versions?page=14&page_size=2"
}
},
"versions": [{
"id": "42",
"changeset": {
"grouped": [
true,
false
]
},
"whodunnit": "stuartlynn",
"created_at": "2014-03-20T06:23:12Z",
"links": {
"item": {
"id": "101",
"href": "/workflows/101",
"type": "workflows"
}
}
},{
"id": "43",
"changeset": {
"prioritized": [
false,
true
]
},
"whodunnit": "stuartlynn",
"created_at": "2014-03-20T06:23:12Z",
"links": {
"item": {
"id": "101",
"href": "/workflows/101",
"type": "workflows"
}
}
}]
}
A Workflow Version resource represents a set of changes made to a Workflow resource.
It has the following attributes:
Attribute | Type | Description |
---|---|---|
id | integer | read-only |
changeset | hash | read-only |
whodunnit | string | read-only |
created_at | datetime | read-only |
It is NOT editable.
List All Workflow Versions
GET /api/workflows/123/versions HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- workflow_id (required, integer) ... integer id of the workflow resource
- page (optional, integer) ... the index of the page to retrieve default is 1
- page_size (optional, integer) ... number of items to include on a page default is 20
Response will have a meta attribute hash containing paging information.
Workflow Versions are returned as an array under versions.
Retrieve a Single Version
GET /api/workflows/123/versions/1 HTTP/1.1
Accept: application/vnd.api+json; version=1
Content-Type: application/json
- Parameters
- workflow_id (required, integer) ... integer id of the workflow resource
- id (required, integer) ... integer id of the version to retrieve