NAV
http python javascript ruby
  • Introduction
  • Authentication
  • JSON-API conventions
  • Headers
  • Aggregations
  • Classifications
  • Collection preferences
  • CollectionRole
  • Collections
  • Memberships
  • Organizations
  • Project Preferences
  • Project Roles
  • Projects
  • SubjectSetImports
  • SetMemberSubjects
  • SubjectSets
  • SubjectWorkflowStatuses
  • Subjects
  • UserGroups
  • Users
  • Workflows
  • 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:

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

    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:

    initial postman req

    get new access token

    1. Token name is used to identify the token in Postman, this is for your reference only
    2. Select the grant type to be ‘Client Credentials’
    3. Use the client ID from the OAuth application you setup at signin.zooniverse.org
    4. Same for client secret
    5. 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
    6. Client authentication - send credentials in the request body
    7. 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
    8. If successful you’ll see a screen with an access token, scroll down and press the ‘Use Token’ button

    access token

    Now the request will have the authentication token setup for use in postman.

    req with access token

    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.

    1. Accept: application/vnd.api+json; version=1
    2. Content-Type: application/json

    add extra req headers

    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’.

    api me response

    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.

    postman console

    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.

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

    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

    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:

    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:

    Any of the scopes may be further filtered using the project_id, workflow_id and user_group_id parameters.

    Parameters

    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

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

    Retrieve a single CollectionPreference [GET]

    Parameters

    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

    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
    

    Retrieve a single CollectionRole

    GET /api/collection_roles/123 HTTP/1.1
    Accept: application/vnd.api+json; version=1
    Content-Type: application/json
    

    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
    

    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
    

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

    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.

    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.

    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
    

    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
    

    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
    

    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
    

    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.

    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.

    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.

    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
    

    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
    

    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.

    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.

    List all ProjectRoles

    GET /api/project_roles HTTP/1.1
    Accept: application/vnd.api+json; version=1
    Content-Type: application/json
    

    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
    

    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.

    List All Projects

    GET /api/projects HTTP/1.1
    Accept: application/vnd.api+json; version=1
    Content-Type: application/json
    

    Retrieve a single Project

    GET /api/projects/123 HTTP/1.1
    Accept: application/vnd.api+json; version=1
    Content-Type: application/json
    

    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:

    1. A researcher uploads image files into a web accessible location (e.g. s3 bucket, azure blob store, etc).
    2. 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.
    3. The researcher will then send the manifest payload to the Zooniverse API programatically
    4. 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.
    5. 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
    

    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:

    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
    

    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
    

    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
    

    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
    

    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.

    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.

    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"]
    }
    
    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.

    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
    

    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
    

    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
    

    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
    

    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
    

    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
    

    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.

    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
    

    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
    

    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.

    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.

    DELETE /user_groups/123/links/users/1,2,3 HTTP/1.1
    Accept: application/vnd.api+json; version=1
    Content-Type: application/json
    

    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
    email 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.

    List Users

    GET /api/users HTTP/1.1
    Accept: application/vnd.api+json; version=1
    Content-Type: application/json
    

    Parameters:

    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.

    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:

    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
    

    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
    

    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.

    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.

    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.

    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
    

    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