OpenMinTeD AERO Protocol 1.0.0

Introduction

The purpose of AERO is to embed a (generic) annotation editor within a service NLP/TDM infrastructure. The protocol focuses on actions triggered by the infrastructure. No dependencies of the annotation editor on the infrastructure are introduced. This ensures that the annotation editor can be embedded in various different infrastructures that support AERO.

An infrastructure often offers multiple services, e.g. a registry/catalog and a storage system. If an annotation editor needs to be aware of these services, it creates a strong coupling of the editor with the surrounding platform and actions such as opening a document or searching for a document can easily require replicating a significant part of the functionality of these other services. Hence, it is more sensible to design a protocol that allows embedding arbitrary annotation editors in a platform without introducing dependencies on the surrounding platform.

Many annotation editors - even web-based ones - do not offer any remote API at all. They cannot be embedded in an infrastructure. Transferring data between the infrastructure and the editor always requires the user importing/exporting the data. AERO provides a set of calls and data structures that enable a basic set of interactions related to managing project, documents, annotations, and curated annotations. As such, it is suitable for annotation editors that support these concepts, e.g. WebAnno, AlvisAE, brat, etc.

API

This section explains the data structures and API calls defined by AERO.

Data Structures

AERO JSON response

The response provides an envelop for a returned data structure. In addition to the actual response in the "body", the envelope contains a field for “messages”. Example:

{
  "messages": [
    { "level": "WARN", "text": "Internal error while accessing document 10.",
  ],
  "body": [
    {
      "id": "32",
      "name": "sample.txt",
      "state": "CURATION_FINISHED"
    },
    {
      "id": "33",
      "name": "essay001.xmi",
      "state": "NEW"
    }
  ]
}

A message always contains a "level" and a "text" field. The text must be a string. Acceptable values for the "level" field are the strings:

Log levels
  • ERROR - if there is an error, then typically the body is empty.

  • WARN - if there is a warning, then the body might be incomplete.

  • INFO - an informative message, typically a confirmation message that the action requested by the client has been performed.

  • DEBUG - an AERO server should never generate debug messages unless specifically configured to do so by its administrator

Constant Values

Document status
  • NEW

  • ANNOTATION-IN-PROGRESS

  • ANNOTATION-COMPLETE

  • CURATION-IN-PROGRESS

  • CURATION-COMPLETE

Annotation status
  • NEW

  • LOCKED

  • IN-PROGRESS

  • COMPLETE

Calls

This section explains the API calls defined by AERO. All the calls are relative to a base URL which depends on the URL where the annotation tool is hosted. It is recommended but not mandatory that the URL includes aero and v1, e.g. http://annotool.myorg.com/api/aero/v1/.

Projects

List Projects

Produce a list of all projects accessible by the current user.

Title

List projects

URL

/projects

Method

GET

Consumes

none

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

none

Data params

none

Success response

Code 200
Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "messages": [],
  "body":[
    {
      "id": "1",
      "name": "Project A"
    },
    {
      "id": "5",
      "name": "Project B"
    },
    {
      "id": "28",
      "name": "Project C"
    }
  ]
}

Error response

Code 403 - Access forbidden
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Permission denied."}
  ]
}
Create Project

Creates a new project. By default, the user that invokes this action receives permissions on the project equivalent to those of a project manager, e.g. the user should be able to add/remove documents to/from the project. If the "creator" parameter is set, then these permissions are granted to the specified user instead of the current user. This is important such that the PLATFORM can invoke this action using an administrative user account on behalf of a real user. The "creator" should in this case be the real user, not the administrative user used by the PLATFORM.

Title

Create project

URL

/projects

Method

POST

Consumes

multipart/form-data

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

none

Data params

  • name - project name (required)

  • creator - username of the owner of the project (optional)

Success response

Code 201
Example
1
2
3
4
5
6
7
{
  "messages": [],
  "body": {
    "id": "13",
    "name": "Test"
  }
}

Error response

Code 403 - Access forbidden
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Permission denied."}
  ]
}
Code 404 - creator user not found

Content: AERO JSON response

Code: 409 - Project with the name already exists

Content: AERO JSON response

Delete Project

Deletes the specified project. This also entails the deletion of all documents and annotations in the project.

Title

Delete project

URL

/projects/{projectId}

Method

DELETE

Consumes

none

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project

Data params

none

Success response

Code 200
Example
1
2
3
4
5
{
  "messages": [
    { "level": "INFO", "text": "Project 13 deleted."}
  ]
}

Error response

Code 403 - Access forbidden
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Permission denied."}
  ]
}
Code 404 - Project not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Project does not exist."}
  ]
}
Import Project

Imports a ZIP archive containing a previously exported project. If a project with the name as indicated by the metadata in the ZIP archive already exists, the imported project is created under a different name. E.g. if the name of the project is "My project" and a project by this name already exists, then the system can create the project under the name "My project 1". The name of the created project and its ID are returned as part of the result.

Title

Import project

URL

/projects/import

Method

POST

Consumes

none

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

  • file - ZIP file

Data params

none

Success response

Code 200
Example
1
2
3
4
5
6
7
{
  "messages": [],
  "body": {
    "id": "13",
    "name": "Test"
  }
}

Error response

Code 403 - Access forbidden
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Permission denied."}
  ]
}
Export Project

Exports the whole project as a ZIP archive. This archive can be imported again using the "Import project" action.

Title

Export project

URL

/projects/{projectId}/export.zip

Method

GET

Consumes

none

Produces

  • application/zip

  • application/json;charset=UTF-8 (AERO JSON response)

URL params

none

Data params

none

Success response

Code 200

Content: ZIP archive

Error response

Code 403 - Access forbidden
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Permission denied."}
  ]
}

Documents

List Documents

List all documents in a project.

Title

List documents

URL

/projects/{projectId}/documents

Method

GET

Consumes

none

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project (mandatory)

Data params

none

Success response

Code 200
Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
  "messages": [],
  "body": [
    {
      "id": "32",
      "name": "sample.txt",
      "state": "CURATION-FINISHED"
    },
    {
      "id": "33",
      "name": "essay001.xmi",
      "state": "NEW"
    },
    {
      "id": "34",
      "name":"essay002.xmi",
      "state":"NEW"
    },
    {
      "id": "18",
      "name":"fi3le.txt",
      "state":"NEW"
    }
  ]
}

Error response

Code 404 - Project not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Project does not exist."}
  ]
}
Create Document

Create/import a new document in the project.

Title

Create document

URL

/projects/{projectId}/documents

Method

POST

Consumes

application/octet-stream

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project (mandatory)

Data params

  • name - name of the document

  • format - format of documents

    • TEXT - only plain text (currently the only format that must be supported by all AERO servers; servers may support other formats)

  • content - the document in the specified format (binary)

  • state - a document state (optional, allowed values: NEW (default), ANNOTATION-IN-PROGRESS, ANNOTATION-FINISHED)

Success response

Code 201
Example
1
2
3
4
5
6
7
{
  "messages": [],
  "body": {
    "id": "33",
    "name": "Essay 12”
  }
}

Error response

Code 404 - Project not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Project does not exist."}
  ]
}
Read Document

Exports the specified document. Unless specified otherwise, the format in which the documents is exported corresponds to the format in which the document was imported or to the default format of the application. The application may choose to indicate the produced format by setting a media type other than application/octet-stream for the response.

It was considered to use content-negotiation instead of the "format" parameter. However, content-negotiation typically uses common mime-types and for many of the formats usually used by annotation editors, there are no suitable mime-types. E.g. one could use "text/tab-separated-values" for CoNLL formats, but that would not convey sufficient information about the semantics of the columns to enable the import/export of the document / which specific CoNLL year to use.

Title

Export document

URL

/projects/{projectId}/documents/{documentId}[?format={format}]

Method

GET

Consumes

none

Produces

  • application/octet-stream

  • application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project (mandatory)

Data params

  • name - name of the document

  • documentId - ID of the document (mandatory)

  • format - format of annotations

    • AUTO - plain text or original format (depending on what is possible

    • ORIGINAL - only original format allowed

    • TEXT - only plain text

    • Other values depending on the format supported by the AE

Success response

Code 200

Content: document

Error response

Code 404 - Project or document not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Project does not exist."}
  ]
}
Delete Document

Delete a document from the project. Deleting the document also deletes all annotations on the document.

Title

Delete document

URL

/projects/{projectId}/documents/{documentId}

Method

DELETE

Consumes

none

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project (mandatory)

  • documentId - ID of the document (mandatory)

Data params

none

Success response

Code 200
Example
1
2
3
4
5
{
  "messages": [
    { "level": "INFO", "text": "Document deleted."}
  ]
}

Error response

Code 404 - Project or document not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Project does not exist."}
  ]
}

Annotations

List Annotations

List annotations in the project.

Title

List annotations

URL

/projects/{projectId}/documents/{documentId}/annotations

Method

GET

Consumes

none

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project (mandatory)

  • `documentId - ID of the document (mandatory)

Data params

none

Success response

Code 201
Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  "messages": [],
  "body": [
    {
      "user":"richard",
      "state":"NEW"
    },
    {
      "user":"anshul",
      "state":"IN-PROGRESS",
      "timestamp":"2016-09-24T10:43:54+0200"
    },
    {
      "user":"abc",
      "state":"COMPLETE",
      "timestamp":"2016-09-24T10:46:28+0200"
    }
  ]
}

Error response

Code 404 - Project or document not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Project does not exist."}
  ]
}
Create Annotations

Create/import annotations on top of an already existing document. We consider here only the simple case which is that if there are already any existing annotations for the designated user, they will be replaced with the annotations that are uploaded - they will not be merged.

Title

Create annotations

URL

/projects/{projectId}/documents/{documentId}/annotations/{annotator}

Method

POST

Consumes

application/octet-stream

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project (mandatory)

  • `documentId - ID of the document (mandatory)

  • `annotator - ID of the user who created the annotations (mandatory)

Data params

  • format - format of annotations

  • content - the document in the specified format (binary)

  • state - an annotation state (optional, allowed values: NEW (default), IN-PROGRESS, COMPLETE)

Success response

Code 200
Example
1
2
3
4
5
{
  "messages": [
    { "level": "INFO", "text": "Annotations imported."}
  ]
}

Error response

Code 404 - Project, document, or annotation not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Project does not exist."}
  ]
}
Code 415 - Unsupported format
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Unsupported format."}
  ]
}
Read Annotations

Read/export annotations for a document.

Title

Read annotations

URL

/projects/{projectId}/documents/{documentId}/annotations/{annotator}[?format={format}]

Method

GET

Consumes

none

Produces

  • application/octet-stream

  • application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project (mandatory)

  • documentId - ID of the document (mandatory)

  • annotator - ID of the user who created the annotations (mandatory)

  • format - format of annotations

    • AUTO - plain text or original format (depending on what is possible

    • ORIGINAL - only original format allowed

    • TEXT - only plain text

    • Other values depending on the format supported by the AE

Data params

none

Success response

Code 200

Content: the annotation file

Error response

Code 404 - Project, document, or annotation not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Project does not exist."}
  ]
}
Delete Annotations

Delete the annotations of a user on a given document from a project.

Title

Delete annotations

URL

/projects/{projectId}/documents/{documentId}/annotations/{annotator}

Method

DELETE

Consumes

none

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project (mandatory)

  • `documentId - ID of the document (mandatory)

  • `annotator - ID of the user who created the annotations (mandatory)

Data params

none

Success response

Code 200
Example
1
2
3
4
5
{
  "messages": [
    { "level": "INFO", "text": "Annotations deleted."}
  ]
}

Error response

Code 404 - Project, document, or annotation not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Project does not exist."}
  ]
}

Curations

List Curations

There is no dedicated call to list curations. The status of the curation process is tracked at the document level and is available via the "list documents" call.

Create Curations

Create/import curated annotations for a document.

Title

Create curations

URL

/projects/{projectId}/documents/{documentId}/curation

Method

POST

Consumes

application/octet-stream

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project (mandatory)

  • documentId - ID of the document (mandatory)

Data params

  • format - format of annotations depending on the format supported by the AE

  • content - the curated annotations in the specified format

  • state - a document state (optional, allowed values: CURATION-IN-PROGRESS (default), CURATION-COMPLETE)

Success response

Code 200
Example
1
2
3
4
5
{
  "messages": [
    { "level": "INFO", "text": "Curation imported."}
  ]
}

Error response

Code 404 - Project, document, or curated annotations not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Document not found."}
  ]
}
Read Curations

Read/export curated annotations for a document.

Title

Read curations

URL

/projects/{projectId}/documents/{documentId}/curation[?format={format}]

Method

GET

Consumes

none

Produces

  • application/octet-stream

  • application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project (mandatory)

  • documentId - ID of the document (mandatory)

  • format - format of annotations

    • AUTO - plain text or original format (depending on what is possible

    • ORIGINAL - only original format allowed

    • TEXT - only plain text

    • Other values depending on the format supported by the AE

Data params

none

Success response

Code 200

Content: the curated annotation file

Error response

Code 404 - Project, document, or annotation not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Project does not exist."}
  ]
}
Delete Curations

Delete curated annotations for a document.

Title

Delete curations

URL

/projects/{projectId}/documents/{documentId}/curation

Method

DELETE

Consumes

application/octet-stream

Produces

application/json;charset=UTF-8 (AERO JSON response)

URL params

  • projectId - ID of the project (mandatory)

  • documentId - ID of the document (mandatory)

Data params

none

Success response

Code 200
Example
1
2
3
4
5
{
  "messages": [
    { "level": "INFO", "text": "Curation deleted."}
  ]
}

Error response

Code 404 - Project, document, or curated annotations not found
Example
1
2
3
4
5
{
  "messages": [
    { "level": "ERROR", "text": "Document not found."}
  ]
}