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:
- Web server (NGINX)
- Application runtime (API server)
- Application runtime (configurable amount of instances, used for asynchronous processing of tasks)
- Database (PostgreSQL)
- Block storage
- Key-value store (Redis, communication between application runtimes)
Various external services are also linked into the platform. Depending on configuration, this includes an email provider and an identity (OAuth) provider.
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
- Enable Assets API
API v13
- Rewrite authentication mechanism to include a refresh token
- Token API: add refresh token mechanism
API v12
- Remove annotations API
/comments
: endpoint removed/conversations
: endpoint removed
API v11.1
- Add
createdAt
,updatedAt
attributes to TopicGET /topics/:id
: addcreatedAt
,updatedAt
metadata
API v11
- Add
pending
,incompatible
andworking
states to PullRequestGET /pullRequests/:id
: modifystate
attribute
- Rename
open
toworking
state in PullRequestGET /pullRequests/:id
: modifystate
attribute
- Add functionality to accept pull requests
PATCH /pullRequests/:id
: addaccept
value forstateEvent
attribute
- Add
age
,country
,gender
androle
attributes to user CoCOSPOST /users
: addage
,country
,gender
androle
attributesGET /users/:id
: addage
,country
,gender
androle
attributesPATCH /users/:id
: addage
,country
,gender
androle
attributes
API v10
- Rename
eventType
tofeedItemType
GET /feedItems
: rename attribute
API v9.1
- Add ability to reject a PR
PATCH /pullRequests/:id
: add endpoint
API v9
- Require a user's current password when setting a new one
PATCH /users/:id
: addcurrent_password
attribute
API v8
- Migrate topic's
state
attribute to aaccess
state machineGET /topics/:id
: removestate
, addaccess
attributePOST /topics/:id
: removestate
, addaccess
attributePATCH /topics/:id
: removestate
, addaccess
attribute
API v7.1
- Add email notifications toggle to user
GET /users/:id
: addalertEmails
attributePOST /users
: addalertEmails
attribute
- Add
topic_forked
Alert typeGET /users/:id/alerts
: addtopic_forked
alert type
API v7
- Implement new versioning scheme
API v6.2
- Add mark as read to Alerts API
PATCH /alerts/:id
: Add endpoint
API v6.1
- Enforce Alert topic relationship
GET /users/:id/alerts
:topic
relationship is now always present
API v6
- Add required commit message
PATCH /topics/:id/content
: Addmessage
attribute
API v5.3
- Add pull request alert types
GET /users/:id/alerts
: Addpr_submitted
,pr_accepted
andpr_rejected
alert types
API v5.2
- Add Pull Requests API
GET /topics/:id/incomingPullRequests
: add endpointGET /topics/:id/outgoingPullRequests
: add endpointPOST /pullRequests
API v5.1
- Add Alerts API
GET /users/:id/alerts
: add endpoint
API v5
- Add feed item type for forked topics
GET /feedItems
: addtopic_forked
aseventType
API v4.1
- Add ability to fork API
GET /topics/:id
: addupstream
andforks
relationshipsPOST /topics/:id/fork
: add endpoint
API v4
- Rename Notifications API to Feed Items API
- Added required, immutable
rootContentItemId
attribute to Topic resourceGET /topics/:id
: addrootContentItemId
attributePOST /topics
: addrootContentItemId
attribute
- Enforced root content item id equal to resource root content item id when updating topic content
PATCH /topics/:id/content
: add validation error response
- Removed dummy identifier constraints for certain endpoints
PATCH /topics/:id/content
: removeid
attributeDELETE /ratings/:id
: removeid
attributePATCH /confirmation
: removeid
attributeDELETE /token
: removeid
attributePATCH /password
: removeid
attribute
- Removed unnecessary Notifications API endpoints
- Removed relationship endpoints (undocumented)
- Enabled OAuth2 authentication
- Add redirect and callback endpoints (undocumented)
API v3
- Added missing confirmation API route
POST /confirmation
: change behaviourPATCH /confirmation
: add endpoint
API v2
- Enforced all requests to include an API version
- All endpoints: see versioning
API v1
- Initial release
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.
- Github: Storage of code. Issues, projects and wiki are not used for persistent information: new issues are to be converted into backlog items at the end of every sprint. Pull requests (and reviews) are the only feature actively used in the development process.
- Travis: Continuous integration. Tests the pushed code, and restricts pull requests only to code successfully tested and 100% covered.
- Slack: Team communication.
- Docker Hub: Automatically builds Docker images for every release.
- Bugsnag: Error tracking of frontend and backend exceptions.
The current Open Webslides server infrastructure consists of three environments (servers):
owsdev
IP address: 157.193.230.127
Host: 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
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://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://my.cocos.education/
URL: https://publications.cocos.education/
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:
- When it was issued (
iat
, issued at) - The unique identifier of the user for whom this token was issued (
sub
, subject) - The token version of the user at the time of issuance (
ver
, version), used for invalidating existing tokens - That this is an access token (
typ
isaccess
)
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 | |
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"
}
]
}