NAV Navbar

Introduction

Welcome to the Open Webslides documentation! This website aggregates the documentation for developers and administrators.

Overview

The Open Webslides platform is split into two components: frontend and backend. The frontend is built in React and uses Redux to store application state. The backend is built in Ruby on Rails and exposes a REST API to the client.

The REST API is based on the JSON-API specification version 1.0. Under certain conditions, the API deviates from the spec or adds its own implementation when a procedure is not described in the specification, such as uploading binary files. For more examples and technical documentation, refer to the JSON-API specification and the implementation in use. All API calls are subject to a predefined format, defined in the JSON-API spec. Part of these requirements is that all HTTP requests should use the application/vnd.api+json MIME type to exchange data.

Nomenclature

The nomenclature in the API is different from the nomenclature that the user sees in the web application.

User-friendly name Developer/API name Description
Topic Independent group of content (course, chapter, ...)
Update Commit Change to the topic
Slide View Read-only view of the content in the form of slides
Course View Read-only view of the content in the form of full-text course
Personal Copy Fork Duplicated, private topic
Original topic Upstream Topic the personal copy was duplicated from
Send updates Send back changes to the original topic
Contribution Pull Request Changes sent back to the original topic

Application architecture

The entire platform runtime is governed by Docker. All components are running in separate containers, from the web server to the database management system. The following components are present in a fully configured and running system:

Various external services are also linked into the platform. Depending on configuration, this includes an email provider and an identity (OAuth) provider.

Architecture

Data model

Data model

Permission model

A topic and its assets are protected by the access attribute. This attribute determines in what context a topic is available and can have the following values:

State Description
public Visible to everyone, sign in not required
protected Visible to everyone, sign in required
private Only visible to owner and collaborators

Permission table

This table demonstrates the permissions given in each context, depending on the access level. Guest indicates a user that is not signed in. Member indicates a user that is signed in. Collaborator indicates a user that is added to the collaborator's list on the topic. Contributor indicates a user that has contributed to the topic. This is not related to the permission level. Owner indicates the owner/creator of a deck.

read indicates read-only access to the topic. write indicates write access to the topic content. admin indicates admin-level access to the topic metadata.

Topic access level User access level Resulting permissions
public Guest read
Member read
Collaborator read, write
Owner read, write, admin
protected Guest
Member read
Collaborator read, write
Owner read, write, admin
private Guest
Member
Collaborator read, write
Owner read, write, admin

CoCOS Project

On certain versions of the platform, additional endpoints and attributes are added to allow for statistics collection and analysis. The version numbers of these platforms are suffixed by -cocos, eg. 11.0.0-cocos. Where a -cocos enabled API server is required in the documentation, the endpoints and attributes are marked by a CoCOS badge.

Changelog

The changelog contains a summary of changes made in a major/minor API release. It should also include a list of endpoints that were modified. For patch release changelogs, see the git tags and commit messages.

API v13.1

API v13

API v12

API v11.1

API v11

API v10

API v9.1

API v9

API v8

API v7.1

API v7

API v6.2

API v6.1

API v6

API v5.3

API v5.2

API v5.1

API v5

API v4.1

API v4

API v3

API v2

API v1

Setup for administrators

Installation and configuration

The platform uses Docker and docker-compose to allow it to be installed and ran on any platform, independent of operating system or distribution. The backend application code itself only has support for Linux. Installing it on a Windows operating system is on your own risk!

$ git clone https://github.com/OpenWebslides/openwebslides-backend.git openwebslides
$ cd openwebslides
$
$ # The frontend code is stored as a git submodule in `web/`.
$ # Initialize and update it to the latest stable version
$ git submodule init
$ git submodule update
$ (cd web && git pull origin master)
$
$ # Configure environment variables
$ cp openwebslides.env.example openwebslides.env
$ nano openwebslides.env
$
$ # Configure the NGINX server by generating DH params
$ openssl dhparam -out nginx/dhparams.pem 2048
$
$ # Configure the server(s) in nginx/sites-available/
$ # Enable the server(s)
$ cd nginx/sites-enabled/
$ ln -s ../sites-available/my.domain.com.conf .
$
$ # Bring up the platform
$ docker build -t openwebslides/openwebslides:latest .
$ docker-compose up -d
$
$ # The Postgres user and database are not automatically created
$ docker-compose exec postgres psql -U postgres -c \
  "CREATE ROLE openwebslides WITH ENCRYPTED PASSWORD 'openwebslides' LOGIN;"
$ docker-compose exec postgres psql -U postgres -c \
  "CREATE DATABASE openwebslides OWNER openwebslides;"
$
$ # Restart the application container to run database migrations.
$ # Migrations are automatically ran on every application container start.
$ docker-compose restart
$
$ # After bringing up the HTTP server, run the CertBot container to request and
$ # retrieve certificates from Let's Encrypt
$ ./certbot.sh my.domain.com
$
$ # Add this command to a monthly crontab to ensure the certificates
$ # (valid for 3 months) will be refreshed in a timely fashion
$ /path/to/openwebslides/certbot.sh my.domain.com

Data storage

The machine-specific data is stored on several Docker volumes, mounted in the relevant containers.

Volume Description
data Contains the local repositories
postgres Contains the PostgreSQL database
redis Contains the Redis database
public Contains the compiled frontend code (regenerated on every build)
upload Contains temporary uploaded files (cleaned on every startup)

Only the first two volumes contain critical data and should be backed up. The public volume is used by the nginx container to serve the static assets. The upload volume is used by the application container to store temporary uploaded data.

Setup for developers

Backend

Make sure your machine has a working installation of the Ruby version required by the project. This version can be found in the .ruby-version file. Usage of RVM is recommended to manage different Ruby versions and sets of gems.

# STEPS FOR INITIAL INSTALLATION
# Clone the repository
$ git clone git@github.com:OpenWebslides/openwebslides-backend.git
$ cd openwebslides-backend

# Use the correct Ruby version
$ rvm use `cat .ruby-version`@`cat .ruby-gemset` --create

# Install dependencies
$ gem install bundler
$ bundle install

# Create repository data and temporary files path
$ mkdir -p data/ tmp/uploads/

# Configure environment variables
$ cp openwebslides.env.example openwebslides.env
$ nano openwebslides.env

# Source environment variables
$ . ./openwebslides.env

# Apply database migrations
$ bundle exec rails db:schema:load

# Start server
$ bundle exec rails server
# STEPS FOR SUBSEQUENT NEW CODE
# Update the repository
$ git pull

# Update dependencies
$ bundle install

# Apply database migrations
$ bundle exec rails db:migrate

# Start server
$ bundle exec rails server
# USEFUL RAKE TASKS
# Suffix every command with `RAILS_ENV=test` to operate on the test database
$ bundle exec rails db:create       # Create database
$ bundle exec rails db:migrate      # Migrate database
$ bundle exec rails db:drop         # Drop database
$ bundle exec rails db:setup        # Create database and load schema
$ bundle exec rails db:reset        # Drop and migrate database
$ bundle exec rails db:schema:load  # Load database schema (use instead of db:migrate on empty databases)
$ bundle exec rails db:clear        # Delete all data in the database
$ bundle exec rails sidekiq:clear   # Clear Sidekiq queue

Sidekiq

In production environment, asynchronous tasks such as manipulating the filesystem repositories are sent to a background queue, implemented using Sidekiq. Communication between the server and the Sidekiq instance require Redis to be present and configured. Background tasks are inlined automatically in the dev and test environment. The asynchronous behaviour can be enabled by specifying the SIDEKIQ_ASYNC environment variable.

# Start Redis
$ systemctl start redis

# Start Sidekiq
$ bundle exec sidekiq

# Start server
$ bundle exec rails server

# Start server with asynchronous processing
$ SIDEKIQ_ASYNC=true bundle exec rails server

In the development server, the Sidekiq Web UI is mounted under /sidekiq.

Making a release

A script is provided to make API releases consistent and easily. When you have finished making changes to your feature/patch, run the script in bin/release with one of the following parameters:

$ # For major releases, resets the minor and patch version numbers to 0
$ bin/release --major
$ # For minor releases, resets the patch version number to 0
$ bin/release --minor
$ # For patch releases
$ bin/release --patch

Don't forget to update the API documentation. Increment the version number twice in source/index.html.md.erb and add an entry to the changelog.

Push your feature/patch branch to Github and open a pull request. Don't forget to push your local tags as well: git push --tags.

Frontend

Make sure your machine has a working installation of the Node version required by the project.

# STEPS FOR INITIAL INSTALLATION
# Clone the repository
$ git clone git@github.com:OpenWebslides/openwebslides-frontend.git
$ cd openwebslides-frontend

# Install dependencies
$ yarn

# Start server
$ yarn run dev-server

Coding style guidelines

Frontend

Write down the guidelines for frontend code here.

Backend

Specs

Use the following templates for every test:

# Controllers
# Models
#
#

For all tests, write down the happy path first, followed by alternate paths wrapped in a context block.


Infrastructure

A lot of tools are used in the development and deployment process.

The current Open Webslides server infrastructure consists of three environments (servers):

owsdev

IP address: 157.193.230.127

Host: owsdev.ugent.be

URL: http://owsdev.ugent.be/

Responsible contact: Florian Dejonckheere

This is the development server. Use this server when developing features and fixes. The version of the platform and stability thereof are not guaranteed. The database and repositories may be wiped at any time.

UGent CAS: The server should run a version without the UGent CAS-functionality, allowing local clients to manipulate the API.

Access: All developers should have access to this server using the openwebslides@owsdev.ugent.be user and their private key. If this is not the case, contact your system administrator and include your public key.

owsqas

IP address: 157.193.231.202

Host: owsqas.ugent.be

URL: https://owsqas.ugent.be/

Responsible contact: Florian Dejonckheere

This is the testing/QA server. Deploy to this server when testing releases before merging. The server should run a stable version.

UGent CAS: The server should run a version with the UGent CAS-functionality, in order to mirror the production environment.

Access: All developers should have access to this server using the openwebslides@owsqas.ugent.be user and their private key. If this is not the case, contact your system administrator and include your public key.

owsprod

IP address: 157.193.231.203

Host: owsprod.ugent.be

URL: https://owsprod.ugent.be/

URL: https://openwebslid.es/

URL: https://openwebslides.ugent.be/

Responsible contact: Florian Dejonckheere

Responsible for openwebslid.es: Ruben Verborgh

This is the production server. Only deploy stable, fully tested releases to this server, and only from the master-branch.

UGent CAS: The server runs a version with the UGent CAS-functionality.

Access: Only your system administrator has access to this server. Direct your queries to your system administrator if you want to deploy a release.

cocos

IP address: 157.193.215.95

Host: cocos.atlantis.ugent.be

URL: https://cocos.education/

URL: https://my.cocos.education/

URL: https://publications.cocos.education/

URL: https://cocos.digital/

Responsible contact: Florian Dejonckheere

This is the server for the CoCOS project. It hosts two WordPress installation on https://cocos.education/ and https://publications.cocos.education/, and one Moodle installation on https://my.cocos.education/.

Deploying on owsdev/owsqas

# SSH into the server
$ ssh openwebslides@owsdev.ugent.be -i /path/to/keyfile

# You're now in /opt/openwebslides. The app is located in /opt/openwebslides/OpenWebslides
$ cd OpenWebslides

# This folder contains the cloned git repository
# You can now navigate to any branch/commit you want to
$ git branch
* (detached from 038655f)
  master
  no-cas

$ git fetch --all
$ git checkout b5c3912

# The platform configuration should already be present and correct
# If this is not the case, refer to the Administrator's setup guide

# Build the application image
$ docker build -t openwebslides/openwebslides:latest .

# Bring down the running application and restart it in the background with the new image
$ docker-compose down; docker-compose up -d

Deploying on owsprod

# SSH into the server
$ ssh openwebslides@owsprod.ugent.be -i /path/to/keyfile

# You're now in /opt/openwebslides. The app is located in /opt/openwebslides/OpenWebslides
$ cd OpenWebslides

# This is again just the cloned git repository
# However it should always be on the `master` branch and only `git pull` should be used
$ git pull

# Build the application image
$ docker build -t openwebslides/openwebslides:latest .

# Before the next step, make sure nobody is using the platform
# Preferably only restart the application during off-peak times

# Bring down the running application and restart it with the new image
# ATTENTION: to enable TLS communication, an alternative docker-compose should be specified
$ docker-compose down; docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Tips

## Opening a Rails console
$ docker-compose exec app bundle exec rails console

## Opening a shell to the `data/` directory
$ docker-compose exec app bash
# cd data/
# ls

API overview

The REST API backend is built in a modular way. The URL structure is kept as simple as possible, avoiding nesting resources where possible.

API endpoint Description
/alerts User alerts API
/assets Topic assets API
/confirmation Authentication API: email confirmation
/feedItems Recent Activity feed API
/oauth OAuth endpoints; not part of the REST API
/password Authentication API: password reset
/pullRequests Pull Request API
/token Authentication API: authentication token
/topics Topics API
/users Users API

For documentation on filtering, sorting, including resources, error responses and other functionality not included on this website, refer to the JSON-API specification.

Authentication

The REST API uses JSON Web Tokens (JWTs) as authentication mechanism. The API expects the token to be included in all API requests on protected endpoints as an Authorization header in the bearer token format. The token is only valid for a limited time, but a renewed token is available on every (successfully authenticated) response as an Authorization header. This new token should be used for subsequent API calls.

GET https://openwebslid.es/api/users HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Authorization: Bearer TOKEN

Don't forget to replace TOKEN with the JWT obtained from the Token API

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
Content-Length: 138

Development

When running the API server in development mode, you can skip the token authentication and instead use user authentication instead. To do this, simply replace the Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9... by User 1 in the Authorization header, where 1 is a unique user identifier. The server will detect this and handle the request like an authenticated request originating from user 1.

Request

GET https://openwebslid.es/api/users/1/alerts HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Authorization: User 1

Versioning

The API is semantically versioned. Every request has to include the required API version in the Accept. The server will then determine if the version is satisfiable and proceed as requested. If the version cannot be satisfied by the server, it will return a HTTP 406 Not Acceptable error. Every response by the server also includes a Content-Type header containing the server's exact version.

The Accept header has to contain two MIME types: the JSON API MIME type (application/vnd.api+json) and an Open Webslides MIME type (application/vnd.openwebslides+json) with a version parameter. The version parameter can contain semantic operators, such as >= and ~>, the latter being Ruby's pessimistic operator. The recommended way to deal with versioned requests is to specify a range of acceptable versions. Some examples are noted below

Version string Resolves to When to use
~>6 >= 6.0.0, < 7.0.0 You require features that are already present in 6.0.0
You do not depend on any additional features added in a later 6.x release
You receive minor (backwards compatible) updates and bug fixes
`~>6.2 >= 6.2.0, < 7.0.0 You require features that are already present in a specific release of 6.x
You do not depend on any additional features added in a later 6.x release
You receive minor (backwards compatible) updates and bug fixes
`~>6.2.3 >= 6.2.3, < 6.3.0 You require features that are already present in a specific release of 6.x
You require a specific bug fix or patch to be present
You do not depend on any additional features added in a later 6.x release
You receive only bug fixes
GET https://openwebslid.es/api/users HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Authorization: Bearer TOKEN

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json, application/vnd.openwebslides+json; version=13.1.0
{...}

Failure response

HTTP/1.1 406 Not Acceptable
Content-Type: application/vnd.api+json, application/vnd.openwebslides+json; version=13.1.0
{
  "errors": [
    {
      "title": "Unacceptable version",
      "detail": "The request cannot be fulfilled due to mismatching API version. The API version is '13.1.0'. This request specified 'some version'.",
      "code": "406",
      "status": "406"
    }
  ]
}

Request headers

Since the API adheres to the JSON-API specification, certain headers are required. For all requests excluding binary uploads, the application/vnd.api+json should be used as MIME type. This means that for all requests, the Accept header should be set to this value (next to the Open Webslides MIME type), and for all requests sending data the Content-Type header should be set to this value. For protected endpoints, a Authorization header is also required in the correct format as described above.

POST https://openwebslid.es/api/topics HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Token: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDU3MjU4NzMsInN1YiI6MSwidmVyIjozfQ.1v_SvE8yQE-z9FiKoFhkWRXx9hJ4kQNRxz1uc8zXFjg
{
  "data": {
    "id": "1",
    "type": "topics",
    "links": {
      "self": "https://openwebslid.es/api/topics/1"
    },
    "attributes": {
      "title": "My First Topic",
      "state": "public_access",
      "description": "This is my first topic.",
      "rootContentItemId": "qyrgv0bcd6",
      "hasOpenPullRequest": false
    },
    "relationships": {
      "user": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/user",
          "related": "https://openwebslid.es/api/topics/1/user"
        }
      },
      "upstream": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/upstream",
          "related": "https://openwebslid.es/api/topics/1/upstream"
        }
      },
      "content": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/content",
          "related": "https://openwebslid.es/api/topics/1/content"
        }
      },
      "forks": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/forks",
          "related": "https://openwebslid.es/api/topics/1/forks"
        }
      },
      "collaborators": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/collaborators",
          "related": "https://openwebslid.es/api/topics/1/collaborators"
        }
      },
      "assets": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/assets",
          "related": "https://openwebslid.es/api/topics/1/assets"
        }
      },
      "conversations": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/conversations",
          "related": "https://openwebslid.es/api/topics/1/conversations"
        }
      }
    },
    "meta": {
      "createdAt": "1541668600",
      "updatedAt": "1541668600"
    }
  }
}

Request body

Refer to the JSON-API specification for a formal definition of request body and the documentation on this website for examples on every API.

HTTP status codes

The API uses the following HTTP error codes:

Status code Description
400 Bad Request -- Invalid data or URL
401 Unauthorized -- Invalid or no API token
403 Forbidden -- Not authorized to perform action
404 Not Found
405 Method Not Allowed
406 Not Acceptable -- Content-Type should be application/vnd.api+json
410 Gone -- Resource has been removed
422 Unprocessable Entity -- Malformed data object
429 Too Many Requests -- Rate limiting in effect (to be included in future updates)
500 Internal Server Error -- The server had a problem. Please try again later.
503 Service Unavailable -- Temporarily offline for maintenance. Please try again later.

JSON API error codes

Besides HTTP status codes, the API provides additional error codes in the returned errors object under the code variable:

Error code Description
100 Validation error
101 Invalid resource
102 Filter not allowed
103 Invalid field value
104 Invalid field
105 Param not allowed
106 Param missing
107 Invalid filter value
109 Key order mismatch
110 Key not included in URL
112 Invalid include
113 Relation exists
114 Invalid sort criteria
115 Invalid links object
116 Type mismatch
117 Invalid page object
118 Invalid page value
119 Invalid field format
120 Invalid filters syntax
121 Save failed
122 Invalid data format
400 Bad request
403 Forbidden
404 Record not found
406 Not acceptable
415 Unsupported media type
423 Locked
500 Internal server error

Alerts API

Get all user alerts

This endpoint retrieves all alerts for a given user. Please note that it is only allowed to retrieve alerts for the current user.

Response attributes

Attribute Type Description
alertType Enum Type of alert. See alert types
read Boolean Whether or not the alert was read by the user. Currently always false, cannot be modified
count optional Integer Number of updates available on the topic (only available when type is topic_updated)
createdAt Integer Timestamp of creation This attribute is included in the meta section.

Response relationships

Relationship Type Plurality Description
user User 1 User for which the alert was generated
topic Topic 1 Topic for which the alert was generated
subject optional User 1 User that submitted/accepted/rejected the pull request/forked the topic (only available when alertType is pr_submitted, pr_accepted, pr_rejected or topic_forked)
pullRequest optional PullRequest 1 Pull request the alert is referring to (only available when alertType is pr_submitted, pr_accepted or pr_rejected)

Alert types

There are currently five alert types requiring the user's attention.

Alert type Description
topic_updated There are commits available on one of the user's topics' upstream
pr_submitted A pull request was submitted on one of the topics the user has access to
pr_accepted A pull request submitted by the user was accepted
pr_rejected A pull request submitted by the user was rejected
topic_forked One of the user's topics was forked

Request

GET https://openwebslid.es/api/users/1/alerts HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Authorization: Bearer TOKEN

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": [
    {
      "id": "1",
      "type": "alerts",
      "links": {
        "self": "https://openwebslid.es/api/alerts/1"
      },
      "attributes": {
        "read": false,
        "alertType": "topic_updated",
        "count": 1
      },
      "relationships": {
        "user": {
          "links": {
            "self": "https://openwebslid.es/api/alerts/1/relationships/user",
            "related": "https://openwebslid.es/api/alerts/1/user"
          }
        },
        "topic": {
          "links": {
            "self": "https://openwebslid.es/api/alerts/1/relationships/topic",
            "related": "https://openwebslid.es/api/alerts/1/topic"
          }
        },
        "subject": {
          "links": {
            "self": "https://openwebslid.es/api/alerts/1/relationships/subject",
            "related": "https://openwebslid.es/api/alerts/1/subject"
          }
        },
        "pullRequest": {
          "links": {
            "self": "https://openwebslid.es/api/alerts/1/relationships/pullRequest",
            "related": "https://openwebslid.es/api/alerts/1/pullRequest"
          }
        }
      },
      "meta": {
        "createdAt": "1541668600"
      }
    },
    {
      "id": "2",
      "type": "alerts",
      "links": {
        "self": "https://openwebslid.es/api/alerts/2"
      },
      "attributes": {
        "read": false,
        "alertType": "pr_submitted"
      },
      "relationships": {
        "user": {
          "links": {
            "self": "https://openwebslid.es/api/alerts/2/relationships/user",
            "related": "https://openwebslid.es/api/alerts/2/user"
          }
        },
        "topic": {
          "links": {
            "self": "https://openwebslid.es/api/alerts/2/relationships/topic",
            "related": "https://openwebslid.es/api/alerts/2/topic"
          }
        },
        "subject": {
          "links": {
            "self": "https://openwebslid.es/api/alerts/2/relationships/subject",
            "related": "https://openwebslid.es/api/alerts/2/subject"
          }
        },
        "pullRequest": {
          "links": {
            "self": "https://openwebslid.es/api/alerts/2/relationships/pullRequest",
            "related": "https://openwebslid.es/api/alerts/2/pullRequest"
          }
        }
      },
      "meta": {
        "createdAt": "1542186670"
      }
    }
  ],
  "links": {
    "first": "https://openwebslid.es/api/alerts?page%5Blimit%5D=10&page%5Boffset%5D=0",
    "last": "https://openwebslid.es/api/alerts?page%5Blimit%5D=10&page%5Boffset%5D=0"
  }
}

Mark alert as read

This endpoint marks an alert as read.

Request attributes

Attribute Type Description
read required Boolean Read status, must be true

Request

PATCH https://openwebslid.es/api/alerts/1 HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
Authorization: Bearer TOKEN
{
  "data": {
    "type": "alerts",
    "id": "1",
    "attributes": {
      "read": true
    }
  }
}

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "alerts",
    "links": {
      "self": "https://openwebslid.es/api/alerts/1"
    },
    "attributes": {
      "read": true,
      "alertType": "topic_updated",
      "count": 1
    },
    "relationships": {
      "user": {
        "links": {
          "self": "https://openwebslid.es/api/alerts/1/relationships/user",
          "related": "https://openwebslid.es/api/alerts/1/user"
        }
      },
      "topic": {
        "links": {
          "self": "https://openwebslid.es/api/alerts/1/relationships/topic",
          "related": "https://openwebslid.es/api/alerts/1/topic"
        }
      },
      "subject": {
        "links": {
          "self": "https://openwebslid.es/api/alerts/1/relationships/subject",
          "related": "https://openwebslid.es/api/alerts/1/subject"
        }
      },
      "pullRequest": {
        "links": {
          "self": "https://openwebslid.es/api/alerts/1/relationships/pullRequest",
          "related": "https://openwebslid.es/api/alerts/1/pullRequest"
        }
      }
    },
    "meta": {
      "createdAt": "1541668600"
    }
  }
}

Failure response

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "must be true",
      "detail": "Read must be true",
      "id": "read#mustBeTrue",
      "code": "100",
      "source": {
        "pointer": "/data/attributes/read"
      },
      "status": "422"
    }
  ]
}

Assets API

Get all topic assets

This endpoint retrieves all assets for a given topic.

Response attributes

See Get an asset.

Request

GET https://openwebslid.es/api/topics/1/assets HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"

Response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": [
    {
      "id": "1",
      "type": "assets",
      "links": {
        "self": "https://openwebslid.es/api/assets/1"
      },
      "attributes": {
        "filename": "my_asset.png"
      },
      "relationships": {
        "topic": {
          "links": {
            "self": "https://openwebslid.es/api/assets/1/relationships/topic",
            "related": "https://openwebslid.es/api/assets/1/topic"
          }
        }
      }
    }
  ],
  "links": {
    "first": "https://openwebslid.es/api/assets?page%5Blimit%5D=10&page%5Boffset%5D=0",
    "last": "https://openwebslid.es/api/assets?page%5Blimit%5D=10&page%5Boffset%5D=0"
  }
}

Create an asset

This endpoint creates an asset for a given topic.

Request attributes

Attribute Type Description
filename required String Filename, has to be unique within the topic

Request

POST https://openwebslid.es/api/topics/1/assets HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: image/png
Content-Disposition: attachment; filename="asset2.png"
Authorization: Bearer TOKEN

< binary file >

Success response

HTTP/1.1 201 Created
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "assets",
    "links": {
      "self": "https://openwebslid.es/api/assets/1"
    },
    "attributes": {
      "filename": "my_asset.png"
    },
    "relationships": {
      "topic": {
        "links": {
          "self": "https://openwebslid.es/api/assets/1/relationships/topic",
          "related": "https://openwebslid.es/api/assets/1/topic"
        }
      }
    }
  },
  "links": {
    "first": "https://openwebslid.es/api/assets?page%5Blimit%5D=10&page%5Boffset%5D=0",
    "last": "https://openwebslid.es/api/assets?page%5Blimit%5D=10&page%5Boffset%5D=0"
  }
}

Failure response

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "can't be blank",
      "detail": "user - can't be blank",
      "code": "100",
      "source": {
        "pointer": "/data/relationships/user"
      },
      "status": "422"
    }
  ]
}

Get an asset

This endpoint retrieves an asset.

Response attributes

Attribute Type Description
filename String Filename

Response relationships

Relationship Type Plurality Description
topic optional Topic 1 Upstream (original) topic

Request

GET https://openwebslid.es/api/assets/1 HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "assets",
    "links": {
      "self": "https://openwebslid.es/api/assets/1"
    },
    "attributes": {
      "filename": "my_asset.png"
    },
    "relationships": {
      "topic": {
        "links": {
          "self": "https://openwebslid.es/api/assets/1/relationships/topic",
          "related": "https://openwebslid.es/api/assets/1/topic"
        }
      }
    }
  },
  "links": {
    "first": "https://openwebslid.es/api/assets?page%5Blimit%5D=10&page%5Boffset%5D=0",
    "last": "https://openwebslid.es/api/assets?page%5Blimit%5D=10&page%5Boffset%5D=0"
  }
}

Failure response

HTTP/1.1 404 Not Found
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Record not found",
      "detail": "The record identified by 1 could not be found.",
      "code": "404",
      "status": "404"
    }
  ]
}

Fetch an asset

This endpoint retrieves the binary asset.

Request

GET https://openwebslid.es/api/topics/1/assets/my_asset.png HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"

Response

HTTP/1.1 200 OK
Content-Type: image/png
Content-Disposition: attachment; filename="asset2.png"
< binary file >

Confirmation API

Request resend confirmation instructions

This endpoint requests resending of the confirmation instructions. An email containing a link to confirm the account is sent to the user.

Request attributes

Attribute Type Description
email required String Account email address

Request

POST https://openwebslid.es/api/confirmation HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
{
  "data": {
    "type": "confirmations",
    "attributes": {
      "email": "foo@bar.com"
    }
  }
}

Success response

HTTP/1.1 204 No Content

Confirm account

This endpoint confirms an account. After a success response, the user can sign in.

Request attributes

Attribute Type Description
confirmationToken required String Opaque token that was included in the email sent to the user

Response attributes

See Get a user.

Request

PATCH https://openwebslid.es/api/confirmation HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
{
  "data": {
    "type": "confirmations",
    "attributes": {
      "confirmationToken": "wqBTxueh1yrBoyHiygmK"
    }
  }
}

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "users",
    "links": {
      "self": "https://openwebslid.es/api/users/1"
    },
    "attributes": {
      "name": "Foo Bar",
      "gravatarHash": "f3ada405ce890b6f8204094deb12d8a8"
    },
    "relationships": {
      "topics": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/topics",
          "related": "https://openwebslid.es/api/users/1/topics"
        }
      },
      "collaborations": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/collaborations",
          "related": "https://openwebslid.es/api/users/1/collaborations"
        }
      }
    }
  }
}

Failure response (invalid confirmation token)

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "is invalid",
      "detail": "Confirmation token is invalid",
      "id": "confirmationToken#invalid",
      "code": "100",
      "source": {
        "pointer": "/data/attributes/confirmationToken"
      },
      "status": "422"
    }
  ]
}

Failure response (already confirmed)

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "was already confirmed, please try signing in",
      "detail": "Email was already confirmed, please try signing in",
      "id": "email#alreadyConfirmed",
      "code": "100",
      "status": "422"
    }
  ]
}

Feed Items API

Get all feed items

This endpoint retrieves all Recent Activity feed items.

Response attributes

Attribute Type Description
feedItemType Enum Type of event. Can be one of topic_created, topic_updated, topic_forked
userName String Name of the user that was involved in the event
topicTitle String Name of the topic that was involved in the event
createdAt Integer Timestamp of creation This attribute is included in the meta section.

Request

GET https://openwebslid.es/api/feedItems HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": [
    {
      "id": "1",
      "type": "feedItems",
      "links": {
        "self": "https://openwebslid.es/api/feedItems/1"
      },
      "attributes": {
        "feedItemType": "topic_created",
        "userName": "Foo",
        "topicTitle": "My First Topic"
      },
      "relationships": {
        "user": {
          "links": {
            "self": "https://openwebslid.es/api/feedItems/1/relationships/user",
            "related": "https://openwebslid.es/api/feedItems/1/user"
          },
          "data": {
            "type": "users",
            "id": "1"
          }
        },
        "topic": {
          "links": {
            "self": "https://openwebslid.es/api/feedItems/1/relationships/topic",
            "related": "https://openwebslid.es/api/feedItems/1/topic"
          },
          "data": {
            "type": "topics",
            "id": "1"
          }
        }
      },
      "meta": {
        "createdAt": "1525700605"
      }
    }
  ],
  "links": {
    "first": "https://openwebslid.es/api/feedItems?page%5Blimit%5D=10&page%5Boffset%5D=0",
    "next": "https://openwebslid.es/api/feedItems?page%5Blimit%5D=10&page%5Boffset%5D=10",
    "last": "https://openwebslid.es/api/feedItems?page%5Blimit%5D=10&page%5Boffset%5D=1"
  }
}

Password API

Request password reset

This endpoint requests a password reset. An email containing a link to reset the account password is sent to the user.

Request attributes

Attribute Type Description
email required String Account email address

Request

POST https://openwebslid.es/api/password HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
{
  "data": {
    "type": "passwords",
    "attributes": {
      "email": "foo@bar.com"
    }
  }
}

Success response

HTTP/1.1 204 No Content

Reset password

This endpoint will update the account password.

Request attributes

Attribute Type Description
resetPasswordToken required String Opaque token that was included in the email sent to the user
password required String Account password

Response attributes

See Get a user.

Request

PATCH https://openwebslid.es/api/password HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
{
  "data": {
    "type": "passwords",
    "attributes": {
      "resetPasswordToken": "HhGsn52e_xu46X6T1PwU",
      "password": "myNewPassword"
    }
  }
}

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "users",
    "links": {
      "self": "https://openwebslid.es/api/users/1"
    },
    "attributes": {
      "name": "Foo Bar",
      "gravatarHash": "f3ada405ce890b6f8204094deb12d8a8"
    },
    "relationships": {
      "topics": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/topics",
          "related": "https://openwebslid.es/api/users/1/topics"
        }
      },
      "collaborations": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/collaborations",
          "related": "https://openwebslid.es/api/users/1/collaborations"
        }
      }
    }
  }
}

Failure response (invalid reset password token)

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "is invalid",
      "detail": "Reset password token is invalid",
      "id": "resetPasswordToken#invalid",
      "code": "100",
      "source": {
        "pointer": "/data/attributes/resetPasswordToken"
      },
      "status": "422"
    }
  ]
}

Failure response (password too short)

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "is too short (minimum is 6 characters)",
      "detail": "Password is too short (minimum is 6 characters)",
      "id": "password#tooShort",
      "code": "100",
      "source": {
        "pointer": "/data/attributes/password"
      },
      "status": "422"
    }
  ]
}

Pull Requests API

Create a pull request

This endpoint creates a pull request.

Request attributes

Attribute Type Description
message required String Message FROM the user submitting the pull request

Request relationships

Relationship Type Plurality Description
user required User 1 The user submitting the pull request
source required Topic 1 The topic which is being merged
target required Topic 1 The topic being merged into

Request

POST https://openwebslid.es/api/pullRequests HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
Authorization: Bearer TOKEN
{
  "data": {
    "type": "pullRequests",
    "attributes": {
      "message": "Fixed some typos in the first chapter."
    },
    "relationships": {
      "user": {
        "data": {
          "id": "1",
          "type": "users"
        }
      },
      "source": {
        "data": {
          "id": "2",
          "type": "topics"
        }
      },
      "target": {
        "data": {
          "id": "1",
          "type": "topics"
        }
      }
    }
  }
}

Success response

HTTP/1.1 201 Created
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "pullRequests",
    "links": {
      "self": "https://openwebslid.es/api/pullRequests/1"
    },
    "attributes": {
      "message": "Fixed some typos in the first chapter.",
      "state": "open"
    },
    "relationships": {
      "user": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/user",
          "related": "https://openwebslid.es/api/pullRequests/1/user"
        }
      },
      "source": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/source",
          "related": "https://openwebslid.es/api/pullRequests/1/source"
        }
      },
      "target": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/target",
          "related": "https://openwebslid.es/api/pullRequests/1/target"
        }
      }
    },
    "meta": {
      "createdAt": "1542044770"
    }
  }
}

Failure response

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "can't be blank",
      "detail": "message - can't be blank",
      "code": "100",
      "source": {
        "pointer": "/data/attributes/message"
      },
      "status": "422"
    }
  ]
}

Failure response

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "can only have on open pull request",
      "detail": "Source can only have on open pull request",
      "id": "source#canOnlyHaveOnOpenPullRequest",
      "code": "100",
      "source": {
        "pointer": "/data/relationships/source"
      },
      "status": "422"
    }
  ]
}

Failure response

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "must have target as upstream",
      "detail": "Source must have target as upstream",
      "id": "source#mustHaveTargetAsUpstream",
      "code": "100",
      "source": {
        "pointer": "/data/relationships/source"
      },
      "status": "422"
    }
  ]
}

Get a pull request

This endpoint retrieves a pull request.

Response attributes

Attribute Type Description
message String Message from user submitting the pull request
feedback String Feedback message to user submitting the pull request
state Enum Status of the pull request (see below)
createdAt Integer Timestamp of creation This attribute is included in the meta section.

Response relationships

Relationship Type Plurality Description
user User 1 The user submitting the pull request
source Topic 1 The topic which is being merged
target Topic 1 The topic being merged into

Pull Request state

The state attribute can have one of the following values. The initial value set by the system is pending. Once the pull request has been checked and deemed compatible to merge, the state is set to ready. If the pull request is not compatible, it is set to incompatible.

A pull request is compatible to merge only if the source topic contains all of the target topic's commits, with some unique commits added.

For example, a pull request merging [A -> B -> C] into [A -> B] is compatible, but a pull request merging [A -> B -> C] into [A -> D] is not. Neither is [A -> B] into [A -> B].

Once a topic owner or one of the collaborators reviews the topic, the state is set to working by the system. When the system has merged the topic (or not), the state is set to accepted (or rejected respectively).

State Description
pending Queued for compatibility check [open]
ready Compatible, ready to be reviewed [open]
incompatible Incompatible, cannot be reviewed [closed]
working Working, processing review [closed]
accepted Reviewed and accepted [closed]
rejected Reviewed and rejected [closed]

Request

GET https://openwebslid.es/api/pullRequests/1 HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "pullRequests",
    "links": {
      "self": "https://openwebslid.es/api/pullRequests/1"
    },
    "attributes": {
      "message": "Fixed some typos in the first chapter.",
      "state": "open"
    },
    "relationships": {
      "user": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/user",
          "related": "https://openwebslid.es/api/pullRequests/1/user"
        }
      },
      "source": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/source",
          "related": "https://openwebslid.es/api/pullRequests/1/source"
        }
      },
      "target": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/target",
          "related": "https://openwebslid.es/api/pullRequests/1/target"
        }
      }
    },
    "meta": {
      "createdAt": "1542044770"
    }
  }
}

Failure response

HTTP/1.1 404 Not Found
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Record not found",
      "detail": "The record identified by 1 could not be found.",
      "code": "404",
      "status": "404"
    }
  ]
}

Reject a pull request

This endpoint rejects a pull request.

Request attributes

Attribute Type Description
stateEvent required String Action to take (reject or accept)
feedback required String Message to the user submitting the pull request

Request

PATCH https://openwebslid.es/api/pullRequests/1 HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
Authorization: Bearer TOKEN
{
  "data": {
    "type": "pullRequests",
    "id": "1",
    "attributes": {
      "stateEvent": "reject",
      "feedback": "I cannot accept this PR."
    }
  }
}

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "pullRequests",
    "links": {
      "self": "https://openwebslid.es/api/pullRequests/1"
    },
    "attributes": {
      "message": "Fixed some typos in the first chapter.",
      "feedback": "I cannot accept this PR.",
      "state": "rejected"
    },
    "relationships": {
      "user": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/user",
          "related": "https://openwebslid.es/api/pullRequests/1/user"
        }
      },
      "source": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/source",
          "related": "https://openwebslid.es/api/pullRequests/1/source"
        }
      },
      "target": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/target",
          "related": "https://openwebslid.es/api/pullRequests/1/target"
        }
      }
    },
    "meta": {
      "createdAt": "1542044770"
    }
  }
}

Failure response (already rejected)

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "cannot transition when rejected",
      "detail": "State event cannot transition when rejected",
      "id": "stateEvent#invalidEvent",
      "code": "100",
      "source": {
        "pointer": "/data/attributes/stateEvent"
      },
      "status": "422"
    }
  ]
}

Failure response (no feedback)

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "can't be blank",
      "detail": "Feedback can't be blank",
      "id": "feedback#blank",
      "code": "100",
      "status": "422"
    }
  ]
}

Accept a pull request

This endpoint accepts a pull request and merges the forked topic into the upstream topic, creating a merge commit.

Request attributes

Attribute Type Description
stateEvent required String Action to take (accept or reject)
feedback String Message to the user submitting the pull request

Request

PATCH https://openwebslid.es/api/pullRequests/1 HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
Authorization: Bearer TOKEN
{
  "data": {
    "type": "pullRequests",
    "id": "1",
    "attributes": {
      "stateEvent": "accept",
      "feedback": "Thank you for your contributions."
    }
  }
}

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "pullRequests",
    "links": {
      "self": "https://openwebslid.es/api/pullRequests/1"
    },
    "attributes": {
      "message": "Fixed some typos in the first chapter.",
      "feedback": "Thank you for your contributions.",
      "state": "accepted"
    },
    "relationships": {
      "user": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/user",
          "related": "https://openwebslid.es/api/pullRequests/1/user"
        }
      },
      "source": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/source",
          "related": "https://openwebslid.es/api/pullRequests/1/source"
        }
      },
      "target": {
        "links": {
          "self": "https://openwebslid.es/api/pullRequests/1/relationships/target",
          "related": "https://openwebslid.es/api/pullRequests/1/target"
        }
      }
    },
    "meta": {
      "createdAt": "1542044770"
    }
  }
}

Failure response (already rejected)

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "cannot transition when rejected",
      "detail": "State event cannot transition when rejected",
      "id": "stateEvent#invalidEvent",
      "code": "100",
      "source": {
        "pointer": "/data/attributes/stateEvent"
      },
      "status": "422"
    }
  ]
}

Token API

Open Webslides uses a two-token authentication mechanism. When the client authenticates against the application, a long-lived token is generated (refresh token). This token is stored by the client for future use. Using the refresh token, a short-lived token can be obtained. This short-lived token (access token) can then be used to manipulate the API.

Refresh tokens are typically valid for long periods (months or years), and access tokens for very short periods (hours).

When at a later moment an HTTP 401 error is encountered by the client during normal operation, the following steps should be undertaken: 1. Discard the expired access token 2. Obtain a new access token using the stored refresh token 3. Repeat the failed request using the new access token

     +--------+                               +---------------+
     |        |---- Authentication Request -->|      POST     |
     |        |                               |     /token    |
     |        |<--------- Refresh Token ------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--------- Refresh Token ------>|     PATCH     |
     | Client |                               |     /token    |
     |        |<--------- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |---------- Access Token ------>|      API      |
     |        |                               |    Endpoint   |
     |        |<------- Protected Resource ---|               |
     +--------+                               +---------------+

Tokens are JWT-encoded strings, that carry information about the user. This information is signed by the API server, but the payload is decodable by the client as well. A typical JWT in Open Webslides will look as following:

eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1NTE3MDg4NTUsInN1YiI6MSwidmVyIjoxLCJ0eXAiOiJhY2Nlc3MifQ.-8r5_UYSISIFFH3M5JtYnu5Fl15GS1gc18L9PL91Ru8

Which decodes to the following payload:

{ "iat": 1551708855, "sub": 1, "ver": 1, "typ": "access" }

The information in this token tells us the following information:

Request refresh token (sign in)

This endpoint obtains a refresh token (signs in a user). This refresh token can only be used to (i) request an access token and (ii) invalidate all tokens (sign out a user). The token is returned in the Authorization header in the bearer token format.

Request attributes

Attribute Type Description
email required String Account email address
password required String Account password

Request

POST https://openwebslid.es/api/token HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
{
  "data": {
    "type": "tokens",
    "attributes": {
      "email": "foo@bar.com",
      "password": "abcd1234"
    }
  }
}

Success response

HTTP/1.1 204 No Content
Content-Type: application/vnd.api+json
Authorization: Bearer TOKEN

Failure response (incorrect credentials, unconfirmed account)

HTTP/1.1 401 Unauthorized
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Create unauthorized",
      "detail": "You don't have permission to create this token.",
      "code": "401",
      "status": "401"
    }
  ]
}

Request access token

This endpoint obtains an access token. This access token can only be used to perform actions on other API endpoints. The token is returned in the Authorization header in the bearer token format.

Request

PATCH https://openwebslid.es/api/token HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Authorization: Bearer TOKEN

Success response

HTTP/1.1 204 No Content
Content-Type: application/vnd.api+json
Authorization: Bearer TOKEN
{
  "data": {
    "id": "1",
    "type": "users",
    "links": {
      "self": "https://openwebslid.es/api/users/1"
    },
    "attributes": {
      "name": "Foo Bar",
      "gravatarHash": "f3ada405ce890b6f8204094deb12d8a8"
    },
    "relationships": {
      "topics": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/topics",
          "related": "https://openwebslid.es/api/users/1/topics"
        }
      },
      "collaborations": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/collaborations",
          "related": "https://openwebslid.es/api/users/1/collaborations"
        }
      },
      "alerts": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/alerts",
          "related": "https://openwebslid.es/api/users/1/alerts"
        }
      }
    }
  }
}

Failure response

HTTP/1.1 401 Unauthorized
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Update unauthorized",
      "detail": "You don't have permission to update this token.",
      "code": "401",
      "status": "401"
    }
  ]
}

Invalidate token (sign out)

This endpoint deletes a token (sign out a user). After a success response, all previously issued tokens for the current user are no longer valid, effectively signing the user out of all sessions.

Request

DELETE https://openwebslid.es/api/token HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Authorization: Bearer TOKEN

Success response

HTTP/1.1 204 No Content

Failure response

HTTP/1.1 401 Unauthorized
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Destroy unauthorized",
      "detail": "You don't have permission to destroy this token.",
      "code": "401",
      "status": "401"
    }
  ]
}

Topics API

Get all topics

This endpoint retrieves all topics.

Response attributes

See Get a topic.

Request

GET https://openwebslid.es/api/topics HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"

Response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": [
    {
      "id": "1",
      "type": "topics",
      "links": {
        "self": "https://openwebslid.es/api/topics/1"
      },
      "attributes": {
        "title": "My First Topic",
        "state": "public_access",
        "description": "This is my first topic.",
        "rootContentItemId": "qyrgv0bcd6",
        "hasOpenPullRequest": false
      },
      "relationships": {
        "user": {
          "links": {
            "self": "https://openwebslid.es/api/topics/1/relationships/user",
            "related": "https://openwebslid.es/api/topics/1/user"
          }
        },
        "upstream": {
          "links": {
            "self": "https://openwebslid.es/api/topics/1/relationships/upstream",
            "related": "https://openwebslid.es/api/topics/1/upstream"
          }
        },
        "content": {
          "links": {
            "self": "https://openwebslid.es/api/topics/1/relationships/content",
            "related": "https://openwebslid.es/api/topics/1/content"
          }
        },
        "forks": {
          "links": {
            "self": "https://openwebslid.es/api/topics/1/relationships/forks",
            "related": "https://openwebslid.es/api/topics/1/forks"
          }
        },
        "collaborators": {
          "links": {
            "self": "https://openwebslid.es/api/topics/1/relationships/collaborators",
            "related": "https://openwebslid.es/api/topics/1/collaborators"
          }
        },
        "assets": {
          "links": {
            "self": "https://openwebslid.es/api/topics/1/relationships/assets",
            "related": "https://openwebslid.es/api/topics/1/assets"
          }
        },
        "conversations": {
          "links": {
            "self": "https://openwebslid.es/api/topics/1/relationships/conversations",
            "related": "https://openwebslid.es/api/topics/1/conversations"
          }
        }
      },
      "meta": {
        "createdAt": "1541668600",
        "updatedAt": "1541668600"
      }
    }
  ],
  "links": {
    "first": "https://openwebslid.es/api/topics?page%5Blimit%5D=10&page%5Boffset%5D=0",
    "last": "https://openwebslid.es/api/topics?page%5Blimit%5D=10&page%5Boffset%5D=0"
  }
}

Create a topic

This endpoint creates a topic.

Request attributes

Attribute Type Description
title required String Name of the topic, does not have to be unique (max 100 characters)
rootContentItemId required String Root content item identifier
description String Description of the topic
access String Access level (See Permission model), defaults to public

Request

POST https://openwebslid.es/api/topics HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
Authorization: Bearer TOKEN
{
  "data": {
    "type": "topics",
    "attributes": {
      "title": "My First Topic",
      "description": "This is my first topic.",
      "state": "public_access",
      "rootContentItemId": "qyrgv0bcd6"
    },
    "relationships": {
      "user": {
        "data": {
          "id": "1",
          "type": "users"
        }
      }
    }
  }
}

Success response

HTTP/1.1 201 Created
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "topics",
    "links": {
      "self": "https://openwebslid.es/api/topics/1"
    },
    "attributes": {
      "title": "My First Topic",
      "state": "public_access",
      "description": "This is my first topic.",
      "rootContentItemId": "qyrgv0bcd6",
      "hasOpenPullRequest": false
    },
    "relationships": {
      "user": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/user",
          "related": "https://openwebslid.es/api/topics/1/user"
        }
      },
      "upstream": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/upstream",
          "related": "https://openwebslid.es/api/topics/1/upstream"
        }
      },
      "content": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/content",
          "related": "https://openwebslid.es/api/topics/1/content"
        }
      },
      "forks": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/forks",
          "related": "https://openwebslid.es/api/topics/1/forks"
        }
      },
      "collaborators": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/collaborators",
          "related": "https://openwebslid.es/api/topics/1/collaborators"
        }
      },
      "assets": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/assets",
          "related": "https://openwebslid.es/api/topics/1/assets"
        }
      },
      "conversations": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/conversations",
          "related": "https://openwebslid.es/api/topics/1/conversations"
        }
      }
    },
    "meta": {
      "createdAt": "1541668600",
      "updatedAt": "1541668600"
    }
  }
}

Failure response

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "can't be blank",
      "detail": "user - can't be blank",
      "code": "100",
      "source": {
        "pointer": "/data/relationships/user"
      },
      "status": "422"
    }
  ]
}

Failure response

HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Invalid field value",
      "detail": "foo is not a valid value for state.",
      "code": "103",
      "status": "400"
    }
  ]
}

Get a topic

This endpoint retrieves a topic.

Response attributes

Attribute Type Description
title String Topic name
state String Access level, see Permission model for more information
rootContentItemId String Root content item identifier
description optional String Topic description
createdAt Integer Timestamp of creation This attribute is included in the meta section.
updatedAt Integer Timestamp of last change This attribute is included in the meta section.
hasOpenPullRequest Boolean Whether or not there is an open outgoing pull request

Response relationships

Relationship Type Plurality Description
upstream optional Topic 0..1 Upstream (original) topic
forks optional Topic 0..n Downstream forks (personal copies)
incomingPullRequests optional PullRequest 0..n Incoming pull requests (topic is target)
outgoingPullRequests optional PullRequest 0..n Outgoing pull requests (topic is source, upstream must be non-empty)

Request

GET https://openwebslid.es/api/topics/1 HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "topics",
    "links": {
      "self": "https://openwebslid.es/api/topics/1"
    },
    "attributes": {
      "title": "My First Topic",
      "state": "public_access",
      "description": "This is my first topic.",
      "rootContentItemId": "qyrgv0bcd6",
      "hasOpenPullRequest": false
    },
    "relationships": {
      "user": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/user",
          "related": "https://openwebslid.es/api/topics/1/user"
        }
      },
      "upstream": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/upstream",
          "related": "https://openwebslid.es/api/topics/1/upstream"
        }
      },
      "content": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/content",
          "related": "https://openwebslid.es/api/topics/1/content"
        }
      },
      "forks": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/forks",
          "related": "https://openwebslid.es/api/topics/1/forks"
        }
      },
      "collaborators": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/collaborators",
          "related": "https://openwebslid.es/api/topics/1/collaborators"
        }
      },
      "assets": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/assets",
          "related": "https://openwebslid.es/api/topics/1/assets"
        }
      },
      "conversations": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/conversations",
          "related": "https://openwebslid.es/api/topics/1/conversations"
        }
      }
    },
    "meta": {
      "createdAt": "1541668600",
      "updatedAt": "1541668600"
    }
  }
}

Failure response

HTTP/1.1 404 Not Found
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Record not found",
      "detail": "The record identified by 1 could not be found.",
      "code": "404",
      "status": "404"
    }
  ]
}

Update a topic

This endpoint updates a topic.

Request attributes

See Create a topic.

Request

PATCH https://openwebslid.es/api/topics/1 HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
Authorization: Bearer TOKEN
{
  "data": {
    "type": "topics",
    "id": "1",
    "attributes" : {
      "title": "My Second Topic",
      "description": "This is my second topic."
    }
  }
}

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "topics",
    "links": {
      "self": "https://openwebslid.es/api/topics/1"
    },
    "attributes": {
      "title": "My Second Topic",
      "state": "public_access",
      "description": "This is my second topic.",
      "rootContentItemId": "qyrgv0bcd6",
      "hasOpenPullRequest": false
    },
    "relationships": {
      "user": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/user",
          "related": "https://openwebslid.es/api/topics/1/user"
        }
      },
      "upstream": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/upstream",
          "related": "https://openwebslid.es/api/topics/1/upstream"
        }
      },
      "content": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/content",
          "related": "https://openwebslid.es/api/topics/1/content"
        }
      },
      "forks": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/forks",
          "related": "https://openwebslid.es/api/topics/1/forks"
        }
      },
      "collaborators": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/collaborators",
          "related": "https://openwebslid.es/api/topics/1/collaborators"
        }
      },
      "assets": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/assets",
          "related": "https://openwebslid.es/api/topics/1/assets"
        }
      },
      "conversations": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/conversations",
          "related": "https://openwebslid.es/api/topics/1/conversations"
        }
      }
    },
    "meta": {
      "createdAt": "1541668600",
      "updatedAt": "1541668600"
    }
  }
}

Failure response

HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Param not allowed",
      "detail": "owner is not allowed.",
      "code": "105",
      "status": "400"
    }
  ]
}

Failure response

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "can't be blank",
      "detail": "title - can't be blank",
      "code": "100",
      "source": {
        "pointer": "/data/attributes/title"
      },
      "status": "422"
    }
  ]
}

Success response

HTTP/1.1 204 No Content

Delete a topic

This endpoint deletes a user.

Request

DELETE https://openwebslid.es/api/topics/1 HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Authorization: Bearer TOKEN

Success response

HTTP/1.1 204 No Content
Content-Type: application/vnd.api+json

Failure response

HTTP/1.1 404 Not Found
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Record not found",
      "detail": "The record identified by 1 could not be found.",
      "code": "404",
      "status": "404"
    }
  ]
}

Get topic content

This endpoint retrieves a topic's content structure.

Response attributes

Attribute Type Description
content String Topic content structure

Request

GET https://openwebslid.es/api/topics/1/content HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "contents",
    "links": {
      "self": "http://localhost:3000/api/contents/1"
    },
    "attributes": {
      "content": [
        {
          "id": "w4lg2u0p1h",
          "type": "contentItemTypes/ROOT",
          "childItemIds": [
            "qflasjgtxr"
          ]
        },
        {
          "id": "qflasjgtxr",
          "type": "contentItemTypes/HEADING",
          "text": "Lorem ipsum",
          "metadata": {
            "tags": [],
            "visibilityOverrides": {}
          },
          "subItemIds": [
            "plqfm799be",
            "a8ntqiiho1"
          ]
        },
        {
          "id": "plqfm799be",
          "type": "contentItemTypes/PARAGRAPH",
          "text": "Lorem **ipsum** dolor `sit` amet, [consectetur](https://www.lipsum.com) adipiscing *elit*.",
          "metadata": {
            "tags": [],
            "visibilityOverrides": {}
          },
          "subItemIds": []
        },
        {
          "id": "a8ntqiiho1",
          "type": "contentItemTypes/PARAGRAPH",
          "text": "Mauris accumsan pretium sem, in volutpat nibh sodales a. Nulla blandit posuere ex, et facilisis dui volutpat in. Fusce tincidunt sed ipsum quis varius. Quisque vitae laoreet sem.",
          "metadata": {
            "tags": [],
            "visibilityOverrides": {}
          },
          "subItemIds": []
        }
      ]
    }
  }
}

Failure response

HTTP/1.1 404 Not Found
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Record not found",
      "detail": "The record identified by 1 could not be found.",
      "code": "404",
      "status": "404"
    }
  ]
}

Update topic content

This endpoint updates a topic's content structure.

Request attributes

Attribute Type Description
content required Array Topic content structure; array of denormalized content items
message required String Commit message

Request

PATCH https://openwebslid.es/api/topics/1/content HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
Authorization: Bearer TOKEN
{
  "data": {
    "type": "contents",
    "id": "1",
    "attributes" : {
      "content": [
        {
          "id": "w4lg2u0p1h",
          "type": "contentItemTypes/ROOT",
          "childItemIds": [
            "qflasjgtxr"
          ]
        },
        {
          "id": "qflasjgtxr",
          "type": "contentItemTypes/HEADING",
          "text": "Lorem ipsum",
          "metadata": {
            "tags": [],
            "visibilityOverrides": {}
          },
          "subItemIds": [
            "plqfm799be",
            "a8ntqiiho1"
          ]
        },
        {
          "id": "plqfm799be",
          "type": "contentItemTypes/PARAGRAPH",
          "text": "Lorem **ipsum** dolor `sit` amet, [consectetur](https://www.lipsum.com) adipiscing *elit*.",
          "metadata": {
            "tags": [],
            "visibilityOverrides": {}
          },
          "subItemIds": []
        },
        {
          "id": "a8ntqiiho1",
          "type": "contentItemTypes/PARAGRAPH",
          "text": "Mauris accumsan pretium sem, in volutpat nibh sodales a. Nulla blandit posuere ex, et facilisis dui volutpat in. Fusce tincidunt sed ipsum quis varius. Quisque vitae laoreet sem.",
          "metadata": {
            "tags": [],
            "visibilityOverrides": {}
          },
          "subItemIds": []
        }
      ]
    }
  }
}

Success response

HTTP/1.1 204 OK
Content-Type: application/vnd.api+json

Failure response

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Invalid root content item",
      "detail": "The identifier of the root content item must match the root content item of the topic.",
      "code": "100",
      "status": "422"
    }
  ]
}

Fork a topic

This endpoint creates a duplicate of the topic, under the current user's account

Request

POST https://openwebslid.es/api/topics/1/fork HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Authorization: Bearer TOKEN

Success response

HTTP/1.1 201 Created
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "topics",
    "links": {
      "self": "https://openwebslid.es/api/topics/1"
    },
    "attributes": {
      "title": "My First Topic",
      "state": "public_access",
      "description": "This is my first topic.",
      "rootContentItemId": "qyrgv0bcd6",
      "hasOpenPullRequest": false
    },
    "relationships": {
      "user": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/user",
          "related": "https://openwebslid.es/api/topics/1/user"
        }
      },
      "upstream": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/upstream",
          "related": "https://openwebslid.es/api/topics/1/upstream"
        }
      },
      "content": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/content",
          "related": "https://openwebslid.es/api/topics/1/content"
        }
      },
      "forks": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/forks",
          "related": "https://openwebslid.es/api/topics/1/forks"
        }
      },
      "collaborators": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/collaborators",
          "related": "https://openwebslid.es/api/topics/1/collaborators"
        }
      },
      "assets": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/assets",
          "related": "https://openwebslid.es/api/topics/1/assets"
        }
      },
      "conversations": {
        "links": {
          "self": "https://openwebslid.es/api/topics/1/relationships/conversations",
          "related": "https://openwebslid.es/api/topics/1/conversations"
        }
      }
    },
    "meta": {
      "createdAt": "1541668600",
      "updatedAt": "1541668600"
    }
  }
}

Failure response

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "cannot be a fork",
      "detail": "Upstream cannot be a fork",
      "id": "upstream#cannotBeAFork",
      "code": "100",
      "status": "422"
    }
  ]
}

Users API

Get all users

This endpoint retrieves all users.

Response attributes

See Get a user.

Request

GET https://openwebslid.es/api/users HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Authorization: Bearer TOKEN

Response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": [
    {
      "id": "1",
      "type": "users",
      "links": {
        "self": "https://openwebslid.es/api/users/1"
      },
      "attributes": {
        "email": "foo@bar.com",
        "name": "Foo Bar",
        "gravatarHash": "f3ada405ce890b6f8204094deb12d8a8"
      },
      "relationships": {
        "topics": {
          "links": {
            "self": "https://openwebslid.es/api/users/1/relationships/topics",
            "related": "https://openwebslid.es/api/users/1/topics"
          }
        },
        "collaborations": {
          "links": {
            "self": "https://openwebslid.es/api/users/1/relationships/collaborations",
            "related": "https://openwebslid.es/api/users/1/collaborations"
          }
        },
        "alerts": {
          "links": {
            "self": "https://openwebslid.es/api/users/1/relationships/alerts",
            "related": "https://openwebslid.es/api/users/1/alerts"
          }
        }
      }
    },
    {
      "id": "2",
      "type": "users",
      "links": {
        "self": "https://openwebslid.es/api/users/2"
      },
      "attributes": {
        "name": "Foo Bat",
        "gravatarHash": "18dded38d16aede5a08ca934f1be2ce0"
      },
      "relationships": {
        "topics": {
          "links": {
            "self": "https://openwebslid.es/api/users/2/relationships/topics",
            "related": "https://openwebslid.es/api/users/2/topics"
          }
        },
        "collaborations": {
          "links": {
            "self": "https://openwebslid.es/api/users/2/relationships/collaborations",
            "related": "https://openwebslid.es/api/users/2/collaborations"
          }
        },
        "alerts": {
          "links": {
            "self": "https://openwebslid.es/api/users/2/relationships/alerts",
            "related": "https://openwebslid.es/api/users/2/alerts"
          }
        }
      }
    }
  ],
  "links": {
    "first": "https://openwebslid.es/api/users?page%5Blimit%5D=10&page%5Boffset%5D=0",
    "last": "https://openwebslid.es/api/users?page%5Blimit%5D=10&page%5Boffset%5D=0"
  }
}

Create a user

This endpoint creates a user. An account has to be confirmed using the Confirmation API in order to obtain a token.

Request attributes

Attribute Type Description
email required String Email, must not be already taken
name required String Full name
password required String Password, must be at least 6 characters
tosAccepted required Boolean User has explicitly accepted terms of service, must be true
alertEmails Boolean Enable email notifications for important alerts, defaults to true
age CoCOS Integer Age
country CoCOS String 2-digit country code
gender CoCOS String Gender, can be male, female or other
role CoCOS String Role, can be learner, teacher or coteacher

Request

POST https://openwebslid.es/api/users HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
{
  "data": {
    "type": "users",
    "attributes": {
      "email": "foo@bar.com",
      "name": "Foo Bar",
      "password": "P@ssword1",
      "tosAccepted": "true"
    }
  }
}

Success response

HTTP/1.1 201 Created
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "users",
    "links": {
      "self": "https://openwebslid.es/api/users/1"
    },
    "attributes": {
      "name": "Foo Bar",
      "gravatarHash": "f3ada405ce890b6f8204094deb12d8a8"
    },
    "relationships": {
      "topics": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/topics",
          "related": "https://openwebslid.es/api/users/1/topics"
        }
      },
      "collaborations": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/collaborations",
          "related": "https://openwebslid.es/api/users/1/collaborations"
        }
      },
      "alerts": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/alerts",
          "related": "https://openwebslid.es/api/users/1/alerts"
        }
      }
    }
  }
}

Failure response

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "has already been taken",
      "detail": "email - has already been taken",
      "code": "100",
      "source": {
        "pointer": "/data/attributes/email"
      },
      "status": "422"
    },
    {
      "title": "can't be blank",
      "detail": "password - can't be blank",
      "code": "100",
      "source": {
        "pointer": "/data/attributes/password"
      },
      "status": "422"
    }
  ]
}

Get a user

This endpoint retrieves a user.

Response attributes

Attribute Type Description
name String Full name
email optional String Email
gravatarHash String MD5 hash for Gravatar service
locale optional String Locale
alertEmails optional Boolean Email notifications for important alerts
age optional CoCOS Integer Age
country optional CoCOS String 2-digit country code
gender optional CoCOS String Gender, can be male, female or other
role optional CoCOS String Role, can be learner, teacher or coteacher

Request

GET https://openwebslid.es/api/users/1 HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "users",
    "links": {
      "self": "https://openwebslid.es/api/users/1"
    },
    "attributes": {
      "name": "Foo Bar",
      "gravatarHash": "f3ada405ce890b6f8204094deb12d8a8"
    },
    "relationships": {
      "topics": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/topics",
          "related": "https://openwebslid.es/api/users/1/topics"
        }
      },
      "collaborations": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/collaborations",
          "related": "https://openwebslid.es/api/users/1/collaborations"
        }
      },
      "alerts": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/alerts",
          "related": "https://openwebslid.es/api/users/1/alerts"
        }
      }
    }
  }
}

Failure response

HTTP/1.1 404 Not Found
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Record not found",
      "detail": "The record identified by 1 could not be found.",
      "code": "404",
      "status": "404"
    }
  ]
}

Update a user

This endpoint updates a user.

Request attributes

Attribute Type Description
name String Full name
locale String Locale
currentPassword String Current password, required when updating password
password String New password, must be at least 6 characters
alertEmails Boolean Email notifications for important alerts
age CoCOS Integer Age
country CoCOS String 2-digit country code (uppercase)
gender CoCOS String Gender, can be male, female or other
role CoCOS String Role, can be learner, teacher or coteacher
device_type CoCOS String Device type, can be desktop, phone or tablet

Request

PATCH https://openwebslid.es/api/users/1 HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Content-Type: application/vnd.api+json
Authorization: Bearer TOKEN
{
  "data": {
    "type": "users",
    "id": "1",
    "attributes": {
      "name": "Foo Bar",
      "currentPassword": "P@ssword1",
      "password": "P@ssword2"
    }
  }
}

Success response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "1",
    "type": "users",
    "links": {
      "self": "https://openwebslid.es/api/users/1"
    },
    "attributes": {
      "name": "Foo Bar",
      "gravatarHash": "f3ada405ce890b6f8204094deb12d8a8"
    },
    "relationships": {
      "topics": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/topics",
          "related": "https://openwebslid.es/api/users/1/topics"
        }
      },
      "collaborations": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/collaborations",
          "related": "https://openwebslid.es/api/users/1/collaborations"
        }
      },
      "alerts": {
        "links": {
          "self": "https://openwebslid.es/api/users/1/relationships/alerts",
          "related": "https://openwebslid.es/api/users/1/alerts"
        }
      }
    }
  }
}

Failure response

HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Param not allowed",
      "detail": "email is not allowed.",
      "code": "105",
      "status": "400"
    }
  ]
}

Failure response

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "can't be blank",
      "detail": "password - can't be blank",
      "code": "100",
      "source": {
        "pointer": "/data/attributes/password"
      },
      "status": "422"
    }
  ]
}

Delete a user

This endpoint deletes a user.

Request

DELETE https://openwebslid.es/api/users/1 HTTP/1.1
Accept: application/vnd.api+json, application/vnd.openwebslides+json; version="~>13.1"
Authorization: Bearer TOKEN

Success response

HTTP/1.1 204 No Content
Content-Type: application/vnd.api+json

Failure response

HTTP/1.1 404 Not Found
Content-Type: application/vnd.api+json
{
  "errors": [
    {
      "title": "Record not found",
      "detail": "The record identified by 1 could not be found.",
      "code": "404",
      "status": "404"
    }
  ]
}