EGC API (1.0-alpha)

Download OpenAPI specification:Download

EGC API

Design considerations

Two-phase send

Sending a new MSI is two-phase (create then send). This is because the msiId value is a critical piece of information for the client (to be able to check status and/or cancel) and the API design must ensure that the client is safely in possession of msiID before a send happens. If the method was one phase then there would be no guarantee that the msiID was received (a failure could happen in any link in the return snetworking chain like a router, firewall, proxy server or indeed a problem at the client application end that prevented persistence of the msiID for later use). Moreover, if the method was one phase and a failure in the network chain occurred then not only would an orphan MSI be sent by the provider but the client would not have knowledge that the MSI had been successfully queued for sending and would naturally retry the send (multiple times even) and we end up with the same MSI being sent 2+ times.

To further clarify the problem being solved by a two phase send here is a discussion of the delivery guarantees of HTTP responses.

Note that a one phase call where the client generated a new unique id (using a UUID for instance) is a possible solution but is less desirable because it introduces a problematic edge case where the client accidentally uses the same id more than once. If two different messages are sent with the same id (concurrently even) then the service should ensure that only one message is accepted and that the service consumer is aware that the other message failed. To do this demands coordination with a single transactional resource (like a relational database) which also demands that that resource is highly available (relational databases are often not great at that during upgrade cycles). There are ways to get high availability (highly available cloud services like DynamoDB and many more can offer conditional updates) but there is a much simpler way with two-phase.

If instead of the one-phase call the server creates the msiId and communicates it to the client then the server side can potentially be scaled with ease if the msiID is a UUID for instance (which is effectively unique without coordination with other nodes).

For example, a highly available and scalable service could be constructed in AWS cloud using API Gateway with Lambda integrations that for the create message and send actions does this

  • Create: Generate a new UUID, place the message content and UUID on to a queue for processing , return the UUID
  • Send: Place the UUID parameter on to a queue for processing

A separate component then actions items on the queue(s). When both the send and create messages have been read then an actual send can take place. What is clear from this design is that many concurrent nodes could be receiving messages without coordinating with a central node/service to ensure id uniqueness.

Note also that to support two-phase send the status value of CREATED is included.

Pagination

The List MSIs action uses a paginated response as the number of MSIs in a response can get large. Pagination can reduce server overhead and improve response times. Client-driven pagination is where the client specifies an offset (skip) field and that number of rows is skipped by the server to return the next page. This can be inefficient for the server-side (see discussion)) and it is preferred to use server-driven pagination which is where each page returned also includes a continuation token to be included in the next page call. The nice thing about this approach is that the server side can simply return an offset in the continuation token if desired but we enable more efficient techniques if wanted later.

Client specific identifiers

Early versions of this API have suggested the inclusion of a NationalSASId field in the created MSI with the purpose of allowing a client to correlate an MSI with its internal data.

This field is a convenience only and thus theoretically should not be included. A client should manage its correlations itself by storing the unique msiId returned by the service paired with its internal identifiers.

If something is required then it should be labelled something like tag and have arbitrary values so that the client can use it for anything. Labelling it NationalSASId suggests more meaning to the field than it may have. TODO confirm.

Geometry

Note that the api below allows for float precision locations for geographic circles and rectangles. An implementation of this API may choose to use the location with reduced precision (for example lat longs rounded to nearest integer).

Cancellation

A PUT to an /msi/[id} path ]with content like {"isCancelled":true} has been suggested as a way of cancelling a broadcast. This can be achieved in a much simpler way with the DELETE verb without content (a cancel action can be considered as a logical delete in the context of this API). A cancelled broadcast cannot be changed in status but can be queried.

Abstraction of C-Codes

Initial proposals for the API suggested a partial abstraction of C-Codes. In particular Priority, MsiType and AreaType were abstracted. This API demonstrates a full abstraction of C-Codes. It is equivalent to C-Codes but has an easier to read and process representation and the mapping to C-Codes then becomes a server-side implementation detail. By using the data modelling constructs of OpenAPI v3 and JSON Schema users can generate code for their API-consuming application that imposes compile-time checking (varies on language) instead of experiencing runtime failures.

TODO is there a requirement for full explicit C-Code support (zero abstraction)?

Auth

Initial proposals for this API included a re-authenticate method whereby a new token was returned if a currently valid token was supplied. This is a security hole in that anyone in possession of one valid token (but not the username and password) can stay authenticated forever. In the same vein, a sensible limit on validity duration of a token should be imposed so that a leaked token cannot be used for long. Given the likely usage of the API (in terms of the number of calls made in a time interval by a client) there should be no significant performance penalty forcing a refresh of the token each hour (or even less).

Bearer authentication is used (RFC6750). Bearer authentication is carried in the Authorization request header in this format:

Authorization: Bearer BASE64_ENCODED_TOKEN

TODO The encoded content of the token is not defined (for example, JWT could be used) but is left to the implementer. Should the authentication flow follow an existing standard like OAuth 2.0?

Naming

Previous API drafts used the field names startDate and endDate for an MSI. Given that those fields refer to timestamps not just dates the names startTime and endTime have been used.

Acknowledgments

Iridium can at times provide receive and read acknowledgements. TODO get better documentation of the capability and a proper specification for their response from a list acks call.

Timings

There may be use cases for the following additional fields on an MSI:

  • createdTime
  • cancelledTime

A user could record in their own systems when they created or cancelled a broadcast but it might help problem diagnosis if that information was together.

TODO confirm

It would also be useful in some circumstances for users to know exactly when a message was broadcast by satellite. Although messages may be scheduled for immediate or later broadcast there may be significant delays till the broadcast occurs and the user should be able to see the actual broadcast times.

TODO discuss with satellite providers

Authenticate

Obtains a token that will be passed in a request header to calls to other paths on this API for authentication and authorization purposes.

Request Body schema: application/json
required

username and password

username
required
string non-empty
password
required
string non-empty
validityMinutes
integer <int32> >= 1

The duration in minutes that the token will be valid, capped by the maximum allowed server-decided duration.
If not supplied (this parameter is optional) then the server default will be applied. Either way the response from this method supplies the expiry time for the token. The token should be refreshed before the expiry time to avoid auth related failures. Note that this field is only a suggestion to the service and may be ignored.

Responses

Request samples

Content type
application/json
{
  • "username": "myrcc",
  • "password": "a-nice-strong-password",
  • "validityMinutes": 60
}

Response samples

Content type
application/json
{
  • "token": "1/mZ1edKKACtPAb7zGlwSzvs72PvhAbGmB8K1ZrGxpcNM",
  • "expiryTime": "2022-04-23T18:25:43.511Z"
}

Create MSI

Submits message content and returns a unique id (across all users) that is to be used in the send method. It is ok for a message to never be sent but the provider should have the freedom to clean up (delete) unsent messages after some reasonable period or after more than N unsent messages are created. (TODO ask providers what is reasonable minimum period and maximum number of unsent messages so it can be documented here).

Authorizations:
bearer
Request Body schema: application/json
required

Describes the message content

required
SARBroadcast (object) or MetBroadcast (object) or NavBroadcast (object) or PiracyBroadcast (object) (Broadcast)

the details of the broadcast particular to the broadcast type

startTime
string <date-time>

the scheduled time of the initial broadcast. If omitted is assumed to be ASAP. A delayed start may not be supported by the service provider, check service provider documentation. TODO confirm

endTime
string <date-time>

the time after which no more broadcasts should be made of this MSI. This field may or may not be honoured by the service provider. The service provider may expect an explicit cancellation for ongoing broadcasts (like CAT-B). TODO confirm

payload
required
string (Payload) [ 1 .. 65535 ] characters

the ASCII message text to broadcast. TODO what max length is appropriate?

echo
boolean
Default: false

If the satellite provider supports echo then setting this field to true will request a repeat broadcast is made a short time after the first (Inmarsat applies a 6 minute interval). Consult the satellite provider documentation about under what circumstances the echo will be honoured.

object (Repetition)
readAcksEnabled
boolean

If the satellite provider supports read acknowledgements then setting this field to true will enable acknowledgements to the satellite provider that the message has been read by the receiving vessel.

receiveAcksEnabled
boolean

If the satellite provider supports receive acknowledgements then setting this field to true will enable acknowledgements to the satellite provider that the message has been received by the vessel.

Responses

Request samples

Content type
application/json
{
  • "broadcast": {
    },
  • "startTime": "2022-04-23T10:30:43.511Z",
  • "endTime": "2022-04-24T10:25:43.511Z",
  • "payload": "a message to be broadcast",
  • "echo": false,
  • "repetition": {
    },
  • "readAcksEnabled": false,
  • "receiveAcksEnabled": false
}

Response samples

Content type
application/json
"289ee192-fdf5-4070-befc-3bf7291c1386"

List MSIs

Returns Maritime Safety Information broadcasts requested to be sent by the user.

Note that none of the parameters are required. If no parameters are supplied then all MSIs for the current user will be returned (paged).

The limit field may not be honoured exactly by the server side (in that it might exceed a maximum limit of the server).

The results of this query may return in any order and that order may vary in repeated calls (for example, the returned MSIs may not be ordered by timestamp). If the client requires an ordering by time then all pages should be requested and then sorted client-side. TODO confirm expectations

Authorizations:
bearer
query Parameters
startTimeMin
string <date-time>
Example: startTimeMin=2022-04-20T18:25:43.511Z

If startTimeMinInclusive is true (the default value if not specified) then filters MSIs on startTime >= startTimeMin.

If startTimeMinInclusive is false then filters MSIs on startTime > startTimeMin.

startTimeMinInclusive
boolean
Default: true
Example: startTimeMinInclusive=true

If startTimeMinInclusive is true (the default value if not specified) then filters MSIs on startTime >= startTimeMin.

If startTimeMinInclusive is false then filters MSIs on startTime > startTimeMin.

If startTimeMinInclusive not specified then has no effect.

startTimeMax
string <date-time>
Example: startTimeMax=2022-04-24T23:25:43.511Z

If startTimeMaxInclusive is true (the default value if not specified) then filters MSIs on startTime <= startTimeMax.

If startTimeMaxInclusive is false then filters MSIs on startTime < startTimeMax.

startTimeMaxInclusive
boolean
Default: true
Example: startTimeMaxInclusive=true

If startTimeMaxInclusive is true (the default value if not specified) then filters MSIs on startTime <= startTimeMax.

If startTimeMaxInclusive is false then filters MSIs on startTime < startTimeMax.

If startTimeMaxInclusive not specified then has no effect.

endTimeMin
string <date-time>
Example: endTimeMin=2022-04-21T18:25:43.511Z

If endTimeMinInclusive is true (the default value if not specified) then filters MSIs on startTime >= startTimeMin.

If startTimeMinInclusive is false then filters MSIs on startTime > startTimeMin.

endTimeMinInclusive
boolean
Example: endTimeMinInclusive=true

If endTimeMinInclusive is true (the default value if not specified) then filters MSIs on endTime >= endTimeMin.

If endTimeMinInclusive is false then filters MSIs on endTime > endTimeMin.

If endTimeMinInclusive not specified then has no effect.

endTimeMax
string <date-time>
Example: endTimeMax=2022-04-25T14:18:23.000Z

If endTimeMaxInclusive is true (the default value if not specified) then filters MSIs on endTime <= endTimeMax.

If endTimeMaxInclusive is false then filters MSIs on endTime < endTimeMax.

endTimeMaxInclusive
boolean
Default: true
Example: endTimeMaxInclusive=true

If endTimeMaxInclusive is true (the default value if not specified) then filters MSIs on endTime <= endTimeMax.

If endTimeMaxInclusive is false then filters MSIs on endTime < endTimeMax.

If endTimeMaxInclusive not specified then has no effect.

limit
integer <int32> >= 1
Default: 10

Requests that at most limit MSIs are returned in the call. The server may cap the requested limit (fewer items may be returned). To request the next page available include the returned continuationToken in the next call. If there are no more items available then the response will not contain a continuationToken.

status
Array of strings (Status)
Items Enum: "CREATED" "SCHEDULED" "ACTIVE" "FINISHED" "CANCELLING" "CANCELLED" "BROADCAST_ERROR" "CANCEL_ERROR"
Example: status=CREATED&status=CANCELLED

Only MSIs that have a status in the given list are returned. If the list is empty (or the parameter is not present) then no filtering on status occurs. TODO support multi-status filtering or just one?

broadcastType
string (BroadcastType)
Enum: "SARBroadcast" "MetBroadcast" "NavBroadcast" "PiracyBroadcast"
Example: broadcastType=SARBroadcast

the type of broadcast

continuationToken
string (ContinuationToken) [ 1 .. 4096 ] characters
Example: continuationToken=10

Describes to the server the starting point of the next page of results and is obtained from the current page. May contain an offset if desired but is at the discretion of implementer. Note that it is possible that a call specifying a continuation token may return en empty list (but an empty list return should not have a continuation token on it so at that point paging would stop).

Responses

Response samples

Content type
application/json
{
  • "msis": [
    ],
  • "continuationToken": 10
}

Get MSI

Returns the details of an MSI broadcast using the unique MSI identifier.

Authorizations:
bearer
path Parameters
id
required
string (MsiId) [ 1 .. 255 ] characters
Example: 289ee192-fdf5-4070-befc-3bf7291c1386

unique msi identifier

Responses

Response samples

Content type
application/json
{
  • "id": "289ee192-fdf5-4070-befc-3bf7291c1386",
  • "broadcast": {
    },
  • "createdTime": "2022-04-23T10:25:43.511Z",
  • "startTime": "2022-04-23T10:30:43.511Z",
  • "endTime": "2022-04-24T10:25:43.511Z",
  • "sentTime": "2022-04-23T10:26:40s.511Z",
  • "cancellingTime": "2022-04-23T10:26:40s.511Z",
  • "cancelledTime": "2022-04-24T13:28:43.511Z",
  • "activeTime": "2022-04-24T13:29:47.511Z",
  • "finishedTime": "2022-04-24T13:45:50.511Z",
  • "errorTime": "2022-04-24T13:48:50.511Z",
  • "payload": "a message to be broadcast",
  • "status": "ACTIVE",
  • "statusMessage": "string",
  • "echo": false,
  • "repetition": {
    },
  • "readAcksEnabled": false,
  • "receiveAcksEnabled": false
}

Send MSI

Requests that an existing unsent MSI be sent. If the MSI has already been sent or the MSI has been cancelled then nothing occurs (this method is idempotent).

Authorizations:
bearer
path Parameters
id
required
string (MsiId) [ 1 .. 255 ] characters
Example: 289ee192-fdf5-4070-befc-3bf7291c1386

unique msi identifier

Responses

Response samples

Content type
{
  • "errorMessage": "an error occurred",
  • "errorType": "SomethingWentWrongException"
}

Cancel MSI

This is a logical delete of a broadcast in that it prevents future broadcasts happening for this msiId (be it a single or repeating broadcast). Once cancelled an MSI cannot be resent. However, the broadcast details are still available to be queried.

Authorizations:
bearer
path Parameters
id
required
string (MsiId) [ 1 .. 255 ] characters
Example: 289ee192-fdf5-4070-befc-3bf7291c1386

unique msi identifier

Responses

Response samples

Content type
{
  • "errorMessage": "an error occurred",
  • "errorType": "SomethingWentWrongException"
}

Get status of an MSI

Returns the status of an MSI broadcast using the unique MSI identifier.

Authorizations:
bearer
path Parameters
id
required
string (MsiId) [ 1 .. 255 ] characters
Example: 289ee192-fdf5-4070-befc-3bf7291c1386

unique msi identifier

Responses

Response samples

Content type
application/json
{
  • "status": "ACTIVE"
}