Newer
Older
drafter-groovy / drafter.yml
# Swagger API Specification for Drafter
swagger: '2.0'
info:
  title: 'Publish My Data: Drafter API'
  description: |
    This document serves as a specification for Drafter's
    API.  Drafter is a backend service used by Publish My Data to
    support PMD's publication workflow.  It describes how clients
    including the PMD application, control data publishing through the
    use of Draftsets.

    The API described in these documents is for manipulating data at
    graph-level, and guiding it through the drafting process. It will
    accept any valid RDF graph contents.

    For display and edit purposes, PublishMyData makes additional
    assumptions about the contents of graphs used for datasets and
    vocabularies.

    Future additions to these APIs will provide mechanisms for
    creating and validating this data conforms to PMD's conventions.

    ## Draftset API Overview

    Draftsets are essentially private working copies, or branches of
    work, that contain changes to RDF data.  When a user creates a
    draftset they effectively create a 'virtual copy' of the live
    sites data in which they can safely make, review and query changes
    before publishing them to the live site.

    When a user creates a draftset they are given a private endpoint
    which they can use to insert, remove or query RDF data through
    standard operations.

    After creating a draftset by `POST`ing to `/draftsets` the client
    is redirected to a REST resource representing the endpoint.

    Once the client knows the draftsets identity it can access a
    number of API endpoints to perform specific tasks or actions.
    These endpoints include:

      - `/query` which is a [SPARQL 1.1](http://www.w3.org/TR/sparql11-protocol/)
         compliant query endpoint bespoke to the current draftset.  By default the
         draftset only includes changes which have been made in the
         draftset, however you can set the optional `union-with-live`
         query parameter to `true` to also include data from the live
         sites endpoint.  If `union-with-live` is true, graphs changed
         in the draftset shadow live graphs of the same name.

      - `/data` which can be used to `POST` (append), `DELETE` or
        `GET` quads from the draftset.

      - `/submit-to` to relinquish ownership of the drafset and either
        assign ownership to another user, or make it available to
        users in a given role. The user which takes ownership of the
        draftset may depending on their role then choose to make
        further ammendments, `/publish` or submit the draftset to a
        new owner.

      - `/publish` which can be used by clients with the `publisher`
        role to publish a reviewed draftset to the live site.

      - `/claim` which a user must call on Draftset's submitted to
        them before they can perform any actions upon them.  Claiming
        a Draftset puts it under the exclusive control of the claiming
        user.  A list of all Draftsets that the current user can lay
        claim to is available under the `/claimable` route.  Users who
        have submitted a Draftset may withdraw it by claiming it back
        providing it has not yet been claimed by another user.

    In addition to these routes there are routes available to list all
    Draftset's in the system and access metadata about an individual
    Draftset.

    ## Long Running Jobs

    Some API actions such as publishing can result in long running
    batch operations.  In these cases an AsyncJob object is returned.
    AsyncJob's contain a path to a `finished-job` route that can be
    polled for notification of the jobs completion.

    Polling this route will result in a HTTP 404 status code until the
    job is finished, at which point it will return a HTTP 200.  Once a
    200 is received the application should inspect the returned JSON
    object to see whether the job completed successfully or resulted
    in an error.

    The server does not store the set of finished-jobs in long term
    persistent storage, so the set of finished-jobs may be lost in
    certain circumstances such as after the service has been
    restarted.  In order to prevent applications waiting forever for a
    lost job to finish, applications should remember and compare
    restart-id's after every poll request.  The server assigns itself
    a new restart-id whenever it is restarted, so if the restart-id
    changes between poll cycles applications can know that the job
    they are awaiting has been lost.

    ## Authentication & Security

    This API is designed to be run over HTTPS/TLS and will use HTTP
    [Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication)
    (RFC 2617) for authentication.

    For example a user `admin@opendatacommunities.org` could attempt
    to authenticate every request to the service described here by
    prefixing the Base64 encoded value of
    `admin@opendatacommunities.org:yourpmdapikey` with the string
    `Basic` followed by a space. For example:

    ````
    Authorization: Basic YWRtaW5Ab3BlbmRhdGFjb21tdW5pdGllcy5vcmc6eW91cnBtZGFwaWtleQ==
    ````

    ## Roles

    Users in Drafter and PMD are assigned to a role which authorises
    them to perform various actions associated with the role and all
    of the roles ranked beneath it.  The roles are currently:

    | rank | role            | Description                                                                          |
    |------|-----------------|--------------------------------------------------------------------------------------|
    |    1 | editor          | Can acess the admin panel and create and edit draftsets.                             |
    |    2 | publisher       | Can do everything an editor can, but also publish to the live site.                  |
    |    3 | manager         | Can do everything a publisher can, but also manage user accounts (not via this API)  |


    Roles are also what users use to exchange Draftsets.  Users submit
    a Draftset to a role, which puts it in that roles pool of
    claimable Draftsets.  Draftsets are then only claimable out of the
    role's pool by users with a role of an equal or higher rank.  In
    addition to this the user who submitted the draftset to the role
    can also withdraw it from submission by claiming it back -
    regarldess of their role's rank.

    Draftsets *must* be claimed before they can be reviewed, published
    or edited.

  version: 1.0.0
securityDefinitions:
  basic-auth:
    type: basic
    description: HTTP Basic Authentication
  jws-auth:
    type: apiKey
    name: Authorization
    in: header
basePath: /v1
tags:
  - name: Draftsets
    description: The publication lifecycle
  - name: Updating Data
    description: Editing Draftset contents
  - name: Metadata
    description: Draftset metadata
  - name: Querying
    description: Accessing Data in Draftsets
  - name: Users
    description: Querying users
  - name: SPARQL Endpoints
    description: SPARQL query endpoints
  - name: Jobs
    description: Async jobs
produces:
  - application/json
consumes:
  - application/json
paths:
  /draftsets:
    post:
      summary: Create a new Draftset
      tags:
        - Draftsets
      description: |
        Creates a new draftset in the database.

        Optionally accepts query string parameters for a name and a description.
      security:
        - jws-auth: []
      parameters:
        - $ref: '#/parameters/display-name'
        - $ref: '#/parameters/draftset-description'
      responses:
        '303':
          description: Upon the creation of a new draftset the caller is redirected to its representation.
    get:
      summary: List available Draftsets
      description: |
       Lists draftsets visible to the user. The include parameter can
       be used to filter the result list to just those owned by the
       current user, or those not owned which can be claimed by the
       current user. By default all owned and claimable draftsets are
       returned.
      security:
        - jws-auth: []
      parameters:
        - $ref: '#/parameters/include'
      tags:
        - Draftsets
      responses:
        '200':
          description: An array of Draftsets
          schema:
            type: array
            items:
              $ref: '#/definitions/Draftset'

  /draftset/{id}:
    get:
      summary: Get information about a Draftset
      description: |
        Returns metadata about the draftset.

        NOTE
      security:
        - jws-auth: []
      parameters:
        - $ref: '#/parameters/id'
      tags:
        - Metadata
      responses:
        '200':
          description: The Draftset.
          schema:
            $ref: '#/definitions/Draftset'
    put:
      summary: Set metadata on Draftset
      description: |
        Sets metadata properties on the draftset, allowing updates to
        the draftsets title and description.
      security:
        - jws-auth: []
      parameters:
        - $ref: '#/parameters/id'
        - $ref: '#/parameters/display-name'
        - $ref: '#/parameters/draftset-description'
      tags:
        - Metadata
      responses:
        '200':
          description: The Draftset.
          schema:
            $ref: '#/definitions/Draftset'
    delete:
      summary: Delete the Draftset and its data
      description: Deletes the draftset and its contents.
      security:
        - jws-auth: []
      parameters:
        - $ref: '#/parameters/id'
        #- $ref: '#/parameters/messagenonote'
      tags:
        - Draftsets
      responses:
        '202':
          description: |
            The request to delete the Draftset was accepted.
            Applications should poll for the completion of the
            AsyncJob.
          schema:
            $ref: '#/definitions/AsyncJob'
  /draftset/{id}/graph:
    put:
      summary: Copy a graph from live into this Draftset
      description: |
        Copies the contents of the specified live graph into this
        Draftset.

        If the specified graph does not exist in live then a 422 error
        will be returned.
      security:
        - jws-auth: []
      parameters:
        - $ref: '#/parameters/id'
        - $ref: '#/parameters/livegraph'
      tags:
        - Updating Data
      responses:
        '202':
          description: The graph was deleted successfully
          schema:
            $ref: '#/definitions/AsyncJob'
    delete:
      summary: Delete the contents of a graph in this Draftset
      description: |
        Schedules the deletion of the specified graph from live and
        deletes its contents from the Draftset.  At publication time
        the specified graph will be removed from the live site.

        If you wish to undo changes you have made in a draftset you
        should not use this route, and should use

        `DELETE /draftset/{id}/changes` instead.

        If the silent is true the request will always complete successfully,
        otherwise if the specified graph does not exist in live then a 422 error
        will be returned.
      security:
        - jws-auth: []
      parameters:
        - $ref: '#/parameters/id'
        - $ref: '#/parameters/reqgraph'
        - $ref: '#/parameters/silent'
      tags:
        - Updating Data
      responses:
        '200':
          schema:
            $ref: '#/definitions/Draftset'
          description: The graph was deleted successfully
        '422':
          description: The graph does not exist in live and the silent is false

  /draftset/{id}/changes:
    delete:
      summary: Remove all the changes to a named graph from the Draftset
      description: |
        Removes all of the changes to the specified graph from the
        Draftset.

        This route is different to `DELETE /draftset/{:id}/graph` in
        that it is about undoing changes you have made and not about
        scheduling deletions against live.

        This route is equivalent to explicitly deleting all the
        triples from a named graph within the draftset with `DELETE
        /draftset/{:id}/data`, the benefit to using this route is that
        you don\'t need to list all the triples contained within the
        graph.
      security:
        - jws-auth: []
      parameters:
        - $ref: '#/parameters/id'
        - $ref: '#/parameters/reqgraph'
      tags:
        - Updating Data
      responses:
        '200':
          description: |
            The request to remove the graph and its changes from the
            Draftset was accepted.  Applications should poll for the
            completion of the AsyncJob.
          schema:
            $ref: '#/definitions/Draftset'

  /draftset/{id}/data:
    put:
      summary: Append the supplied RDF data to this Draftset
      description: |
        Appends the supplied data to the Draftset identified by this
        resource.

        If the RDF data is supplied in a quad serialisation then the
        graph query parameter can be ommited.  If quads are uploaded
        and a graph parameter is specified the graph parameter will
        take precedence, causing all quads to be loaded into the same
        graph.

        If a graph parameter is supplied then
        the RDF data can be supplied in a triple serialisation.
      security:
        - jws-auth: []
      parameters:
        - $ref: "#/parameters/id"
        - $ref: '#/parameters/rdfdata'
        - $ref: '#/parameters/graph'
        #- $ref: '#/parameters/messagenonote'
      consumes:
        - application/n-quads
        - application/trig
        - application/trix
        - application/n-triples
        - application/rdf+xml
        - text/turtle
      produces:
        - application/json
      tags:
        - Updating Data
      responses:
        '202':
          description: |
            The request to append data to the Draftset was accepted.
            Applications should poll for the completion of the
            AsyncJob.
          schema:
            $ref: '#/definitions/AsyncJob'
    delete:
      summary: Remove the supplied RDF data from this Draftset
      description: |
        Removes the supplied data from the Draftset identified by this
        resource.

        If the RDF data is supplied in a quad serialisation then the graph query parameter can be ommited, and the supplied quads will be removed from this Draftset.

        If quads are uploaded and a graph parameter is specified all quads will be treated as if they are triples in the specified graph, and will be removed from it.

        If a graph parameter is supplied then
        the RDF data can be supplied in a triple serialisation.  The supplied triples will be removed from the Draftset.
      security:
        - jws-auth: []
      parameters:
        - $ref: "#/parameters/id"
        - $ref: '#/parameters/rdfdata'
        - $ref: '#/parameters/graph'
        #- $ref: '#/parameters/messagenonote'
      consumes:
        - application/n-quads
        - application/trig
        - application/trix
        - application/n-triples
        - application/rdf+xml
        - text/turtle
      produces:
        - application/json
      tags:
        - Updating Data
      responses:
        '202':
          description: |
            The request to append data to the Draftset was accepted.
            Applications should poll for the completion of the
            AsyncJob.
          schema:
            $ref: '#/definitions/AsyncJob'
    get:
      parameters:
        - $ref: "#/parameters/id"
        - $ref: '#/parameters/graph'
        - $ref: '#/parameters/union-with-live'
        - $ref: '#/parameters/timeout'
      summary: Access the quads inside this Draftset
      description: |
        Request the contents of this draftset in any supported RDF
        serialisation.

        If the chosen serialisation is a triple based one then the
        graph query string parameter must be provided.  If a quad
        based serialisation is chosen then the graph parameter must be
        omitted or a 415 error will be returned.

      security:
        - jws-auth: []
      produces:
        - application/n-quads
        - application/trig
        - apllication/trix
        - application/n-triples
        - application/rdf+xml
        - text/turtle
      tags:
        - Querying
      responses:
        '200':
          description: The Data in the draftset.
          schema:
            type: file
  /draftset/{id}/submit-to:
    post:
      summary: Submit a Draftset to a user or role
      description: |
        Submits this draftset for review and potential publication.
        Draftsets are submitted directly to a user, or into a pool for
        users of a given role.

        Users with a role greater than or equal to the role the
        draftset was submitted to can then lay claim to it.
      security:
        - jws-auth: []
      parameters:
        - $ref: '#/parameters/id'
        - $ref: '#/parameters/role'
        - $ref: '#/parameters/submit-user'
#        - $ref: '#/parameters/message'
#        - $ref: '#/parameters/note'
      tags:
        - Draftsets
      responses:
        '200':
          description: The Draftset was successfully submitted.
          schema:
            $ref: '#/definitions/Draftset'
        '422':
          description: The submit request could not be processed.
  /draftset/{id}/claim:
    put:
      summary: Claim this draftset as your own
      description: |
        Sets the Draftset's `current-owner` to be the same as the user
        performing this operation.  This is necessary to prevent
        other's from making changes to the data contained within the
        Draftset.

        Each role in the system has a pool of 0 or more claimable
        draftsets associated with it.  Claimable draftsets are
        draftsets in a pool where the rank of the pools role is less
        than or equal to the user's role's rank.
      security:
        - jws-auth: []
      parameters:
        - $ref: '#/parameters/id'
        #- $ref: '#/parameters/messagenonote'
      tags:
        - Draftsets
      responses:
        '200':
          description: You were successfully set to be the `current-owner` of this draftset.
          schema:
            $ref: '#/definitions/Draftset'
  /draftset/{id}/publish:
    post:
      summary: Publish the specified Draftset
      description: |
        Requests that this Draftset is published asynchronously to the live site.  If a job is successfully scheduled then an AsyncJob object will be returned.
      security:
        - jws-auth: []
      parameters:
        - $ref: '#/parameters/id'
        #- $ref: '#/parameters/messagenonote'
      tags:
        - Draftsets
      responses:
        '202':
          description: The Draftset is successfully scheduled for publication.
          schema:
            $ref: '#/definitions/AsyncJob'
  /draftset/{id}/query:
    get:
      summary: Query this Draftset with SPARQL
      description: |
        Query this Draftset via the SPARQL query language and protocol.

        Please consult the SPARQL query protocol specification http://www.w3.org/TR/sparql11-protocol/ for a description of this endpoint.
      security:
        - jws-auth: []
      consumes:
        - application/sparql-query
      produces:
        - application/n-triples
        - application/rdf+xml
        - text/turtle
        - application/sparql-results+xml
        - application/sparql-results+json
        - text/csv
      parameters:
        - $ref: '#/parameters/id'
        - $ref: '#/parameters/query'
        - $ref: '#/parameters/union-with-live'
        - $ref: '#/parameters/timeout'

      tags:
        - Querying
      responses:
        '200':
          description: The query results returned according to the SPARQL specification.
          schema:
            type: file
    post:
      summary: Query this Draftset with SPARQL
      description: |
        Query this Draftset via the SPARQL query language and protocol.

        Please consult the SPARQL query protocol specification http://www.w3.org/TR/sparql11-protocol/ for a description of this endpoint.
      security:
        - jws-auth: []
      consumes:
        - application/x-www-form-urlencoded
      produces:
        - application/n-triples
        - application/rdf+xml
        - text/turtle
        - application/sparql-results+xml
        - application/sparql-results+json
        - text/csv
      parameters:
        - $ref: '#/parameters/id'
        - $ref: '#/parameters/post_query'
        - $ref: '#/parameters/union-with-live'
        - $ref: '#/parameters/timeout'
      tags:
        - Querying
      responses:
        '200':
          description: The query results returned according to the SPARQL specification.
          schema:
            type: file
  /sparql/live:
    get:
      summary: Queries the published data with SPARQL
      description: |
        Query the live data via the SPARQL query langauge and protocol.
        Please consult the SPARQL query protocol specification http://www.w3.org/TR/sparql11-protocol/ for a description of this endpoint.
      consumes:
        - application/x-www-form-urlencoded
      produces:
        - application/n-triples
        - application/rdf+xml
        - text/turtle
        - application/sparql-results+xml
        - application/sparql-results+json
        - text/csv
      parameters:
        - $ref: '#/parameters/query'
        - $ref: '#/parameters/timeout'
      tags:
        - SPARQL Endpoints
      responses:
        '200':
          description: The query results returned according to the SPARQL specificiation.
          schema:
            type: file
    post:
      summary: Queries the published data with SPARQL
      description: |
        Query the live data via the SPARQL query langauge and protocol.
        Please consult the SPARQL query protocol specification http://www.w3.org/TR/sparql11-protocol/ for a description of this endpoint.
      consumes:
        - application/x-www-form-urlencoded
      produces:
        - application/n-triples
        - application/rdf+xml
        - text/turtle
        - application/sparql-results+xml
        - application/sparql-results+json
        - text/csv
      parameters:
        - $ref: '#/parameters/post_query'
      tags:
        - SPARQL Endpoints
      responses:
        '200':
          description: The query results returned according to the SPARQL specificiation.
          schema:
            type: file
  /users:
    get:
      summary: Gets all users
      description: |
        Returns a JSON document containing an array of summary
        documents, one for each known user.
      security:
        - jws-auth: []
      tags:
        - Users
      responses:
        '200':
          description: Users found.
          schema:
            type: array
            items:
              $ref: '#/definitions/User'

  /status/finished-jobs/{jobid}:
    get:
      summary: Poll to see if asynchronous job has finished
      description: |
        Poll this route until the AsyncJob is finished.  Whilst the
        job is ongoing this route will return a 404 until it is
        finished.  When the job finishes, through either successful
        completion or an error this route will return a 200 with a
        JSON object indicating the success or failure of the task.

        The server does not store the set of finished-jobs in
        persistent storage, so in exceptional circumstances the set of
        finished-jobs may be lost such as after the service has been
        restarted.

        In order to prevent applications waiting forever for a lost
        job to finish, applications should remember and compare
        restart-id's after every poll request.

        The server assigns itself a new unique restart-id when it is
        started, so if an application detects a change in the
        restart-id between poll cycles they know that the job they are
        awaiting has been lost, and that they should propogate an
        appropriate error.

      parameters:
        - $ref: "#/parameters/jobid"
      tags:
          - Jobs
      responses:
        '404':
          description: The job is not yet finished.
        '200':
          description: The job has finished.  To determine whether the job finished successfully or through a failure you will need to inspect the returned JSON object.
          schema:
            $ref: '#/definitions/FinishedJob'

  /status/writes-locked:
    get:
      summary: Poll to see if the system is accepting writes
      description: |
        During a publish operation operations that create writes such
        as creating a draftset and updating it are temporarily
        disabled and will cause a 503.

        You can poll this route to see if the application is available
        for writes.

        This route exists to give users & user interfaces information
        as to whether the system is available for writes or not.  It
        is not necessary (or desirable) for applications to check this
        route before performing an operation.  Any operation that
        creates writes may 503.

        Returns a boolean true if the system is locked for writes and
        false if it isn't.'
      tags:
          - Jobs
      responses:
        '200':
          description: The request returned the status of the writes lock successfully.
          schema:
            $ref: '#/definitions/WritesLocked'
parameters:
  id:
    name: id
    description: ID of the Draftset
    in: path
    required: true
    type: string
  display-name:
    name: display-name
    description: The name of the Draftset
    in: query
    required: false
    type: string
  draftset-description:
    name: description
    description: A description of the Draftset
    in: query
    required: false
    type: string
  role:
    name: role
    description: The role to submit the draftset to
    in: query
    required: false
    type: string
    enum:
      - editor
      - publisher
      - manager
  submit-user:
    name: user
    description: The username of the user to submit the draftset to.
    in: query
    required: false
    type: string

  include:
    name: include
    in: query
    description: which visible draftsets to include in the results
    required: false
    type: string
    enum:
      - owned
      - claimable
      - all
    default: all

  timeout:
    name: timeout
    in: query
    description: Request a desired timeout in seconds after which the query/operation will be aborted.  You may be granted less than you ask for.
    required: false
    type: integer

# message:
#   name: message
#   description: |
#     A log message to be associated with the performed action.  The
#     message parameter differs from the note parameter in that it is
#     intended for fine grained log and audit trails.
#   in: query
#   required: false
#   type: string

# messagenonote:
#   name: message
#   description: |
#     A log message to be associated with the performed action.
#   in: query
#   required: false
#   type: string

# note:
#   name: note
#   description: |
#     A note to a reviewer / submitter.  This parameter differs from
#     the message parameter in that notes are meant to enable
#     communication between reviewers and submitters.
#   in: query
#   required: false
#   type: string
  jobid:
    name: jobid
    description: ID of the Draftset
    in: path
    required: true
    type: string
  rdfdata:
    name: data
    description: |
      RDF data in a supported serialization format.  If the format is a triple
      based serialisation then the graph parameter must be specified.
    in: body
    required: true
    schema:
      type: string
  graph:
    name: graph
    description: |
      The URI of the named graph that the operation should be
      performed on.  This is only required if the supplied RDF data is
      in triples format.  If quads are provided then all the quads are
      assumed to be in this graph.
    in: query
    required: false
    type: string
  reqgraph:
    name: graph
    description: |
      The URI of the named graph that the operation should be
      performed on.
    in: query
    required: true
    type: string
  livegraph:
    name: graph
    description: |
      The URI of the live graph that the operation should be
      performed on.
    in: query
    required: true
    type: string
  query:
    name: query
    description: URI Encoded SPARQL Query
    in: query
    required: true
    type: string
  post_query:
    name: query
    description: URI Encoded SPARQL Query in the HTTP body
    in: formData
    required: true
    type: string
  union-with-live:
    name: union-with-live
    description: Whether or not the query should run against the union of this draftset with the live site.
    in: query
    required: false
    type: boolean
    default: false
  silent:
    name: silent
    in: query
    required: false
    type: boolean
    allowEmptyValue: true
    default: false

definitions:
  Graph:
    type: object
    description: A graph object
    properties:
      status:
        type: string
        enum:
          - created
          - updated
          - deleted

  User:
    type: object
    required: [username, role]
    properties:
      username:
        type: string
        description: Username of the user
      role:
        type: string
        description: role of the user
    example:
      username: user@example.com
      role: publisher

  Draftset:
    type: object
    required: [id, changes, updated-at, created-at, created-by]
    properties:
      id:
        type: string
        format: uuid
        description: 'Unique identifier representing this draftset'
      created-by:
        type: string
        description: The user who created this Draftset
      changes:
        type: object
        additionalProperties:
          $ref: '#/definitions/Graph'
      display-name:
        type: string
        description: Display name of the Draftset
      current-owner:
        type: string
        description: The current owner of this Draftset
      submitted-by:
        type: string
        description: The owner who submitted this Draftset for review
      claim-role:
        type: string
        enum:
          - editor
          - publisher
          - manager
        description: The required role for users who can claim this Draftset
      claim-user:
        type: string
        description: The user who can claim this Draftset
      description:
        type: string
        description: A description of the Draftset
      updated-at:
        type: string
        format: date-time
        description: IS0 8601 DateTime representing the time the draftsets metadata was last updated
      created-at:
        type: string
        format: date-time
        description: IS0 8601 DateTime representing the time the draftset was created
      # note:
      #   type: string
      #   description: |
      #     A note that can be used by users to communicate the status
      #     of a submission, why a draftset was returned etc.
    example:
      id: de305d54-75b4-431b-adb2-eb6b9e546014
      changes:
        'http://opendatacommunities.org/graph/homelessness/households-accommodated/temporary-housing-types': {'status': 'updated'}
        'http://opendatacommunities.org/data/labour-force/employment-rate/employment-rate-by-age': {'status': 'deleted'}
      display-name: New Temporary Housing Figures
      description: Quarterly updates for Q4 2015
      updated-at: 2016-01-04T13:35:21+00:00
      created-at: 2016-01-01T13:35:21+00:00
      current-owner: admin@opendatacommunities.org
      submitted-by: editor@opendatacommunities.org

  Error:
    type: object
    required: [type, error-type, exception]
    properties:
      type:
        type: string
        enum:
          - error
      error-type:
        type: string
        description: String representing the class of error that occurred
      exception:
        type: object
        required: [message]
        properties:
          message:
            type: string
            description: An error message relating to the specific exception

  WritesLocked:
    type: boolean
    description: |
      True when the system is unavailable for write operations, and false
      when it is accepting them.

  AsyncJob:
    type: object
    description: A successfully submitted Asynchronous Job.
    required: [type, finished-job, restart-id]
    properties:
      type:
        type: string
        enum:
          - ok
          - error
      finished-job:
        type: string
      restart-id:
        type: string
    example:
      type: ok
      restart-id: b1b26596-2dca-4e52-883c-7fdcb8b4be97
      finished-job: /v1/status/finished-jobs/2c4111e5-a299-4526-8327-bad5996de400
  FinishedJob:
    type: object
    description: An Asynchronous Job that completed without error.
    required: [type, restart-id]
    properties:
      type:
        type: string
        enum:
          - ok
          - error
          - not-found
      restart-id:
        type: string
      error-class:
        type: string
      message:
        type: string
      details:
        type: object
    example:
      type: ok
      restart-id: b1b26596-2dca-4e52-883c-7fdcb8b4be97