Using the API

Authentication

API consumers can authenticate themselves either by providing the username and password credentials according to the Basic HTTP Authentication Scheme or by providing an OAuth 2.0 access token according to the The OAuth 2.0 Authorization Framework: Bearer Token Usage. Using the web client a partner can sign up for an account using an email address, choose a password and verify the email address by clicking a link in an email which is sent upon registration. The partner can also reset the password using the web client. Both API authentication methods rely on the email and password credentials.

Note that in the examples below some HTTP headers have been removed for brevity.

Basic authentication

In a Basic Authentication the credentials are included in the Authorization header. This is done by concatenating the credential pair using a colon and base64 encoding the result, base64(<email>:<password>).

The header thus becomes:

Authorization: Basic <base64 encoded credentials> 

Example:

$ curl -v -s --user '[email protected]:password' https://api.monerium.app/orders
> GET /orders HTTP/1.1
> Host: api.monerium.app
> Authorization: Basic dXNlckBleGFtcGxlLmNvbTpwYXNzd29yZA==
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8

Bearer authentication

In a Bearer Authentication the credentials are included in the Authorization header. The access token, which is used as a bearer token, can be acquired using either of the following OAuth 2.0 flows:

Example accessing REST resources using the access token:

$ curl -v -s --user '[email protected]:password' https://api.monerium.app/orders
> GET /orders HTTP/1.1
> Host: api.monerium.app
> Authorization: Bearer slBcjO-QTJGGMRbYTJHq8A
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8

Example accessing WebSocket resources using the access token:

Browsers do not permit setting an HTTP header when opening a WebSocket and therefore most WebSocket libraries, especially those written in JavaScript, do not support adding the access token as a bearer token in the authorization header. For that reason, the access token can be passed in the query parameters when connecting to WebSocket resources.

wss://api.monerium.dev/orders?access_token=MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3

Authorization

Authorization code flow with proof key for code exchange (PKCE)

When public clients, e.g. native or single-page applications, request access tokens, some additional security concerns are posed that are not mitigated by the authorization code flow alone. This is because:

Native apps
  • Cannot securely store a client secret. Decompiling the app will reveal the client secret, which is bound to the app and is the same for all users and devices.
  • May make use of a custom URL scheme to capture redirects, e.g. MyApp://, potentially allowing malicious applications to receive an authorization code from your authorization server.
Single page apps
  • Cannot securely store a client secret because their entire source is available to the browser.

Given this, OAuth 2.0 provides a version of the authorization code flow which makes use of a proof key for code exchange (PKCE) (defined in OAuth 2.0 RFC 7636). The PKCE-enhanced authorization code flow introduces a secret created by the calling application that can be verified by the authorization server; this secret is called the code verifier. Additionally, the calling app creates a code challenge, by hashing the code verifier, and sends this value over HTTPS to retrieve an authorization code. This way, a malicious attacker can only intercept the authorization code but they cannot exchange it for a token without the code verifier.

At a high level, the entire authorization flow for a partner application looks a like this:

1. Generating the code challenge for PKCE in OAuth 2.0
When the user initiates an authentication flow, the client should compute a code_verifier. This must be a random, high entropy string between 43 and 128 characters. Next up, the client computes a code_challenge starting from the code_verifier (see also rfc7636, section 4). This is the result of the following pseudo-code:

code_challenge = base64urlEncode(SHA256(ASCII(code_verifier)))

The code_challenge must be sent in the first step of the authorization flow. The code_verifier instead must be included along the initial request to the authorization server for requesting the Access Token.

2. Authorization code request query parameters
The authorization flow begins with the application directing the user to the Monerium API by either POST or GET request to the /auth endpoint, sending the code_challenge, so it can be verified later.

Endpoint documentation: Initiating the authorization flow.

3-4. Authorization and onboarding
During the authorization flow, the users are automatically directed to a Monerium authorization screen that can be styled to fit the application. The user either authenticates with their username or passwords or signs up. After they have successfully on-boarded, they grant your application access.

5. Authorization response
Once the authorization is granted, users will be redirected to the redirect URL with the authorization code as a query parameter. If you include a state parameter in the initial authorization URL, it will be included in the redirect URL after the user authorizes your app.

Your app should compare the state with the state it created in the initial request. This helps ensure that you only exchange authorization codes that you requested, preventing attackers from redirecting to your callback URL with arbitrary or stolen authorization codes.

Example authorization code successful response:

HTTP/2 301
Location: https://app.com/landingpage
?code=123456789d&state=session-123

Error responses may also be sent to the redirect URL so the application can handle them appropriately:

Error Parameter Description
error An error code string that can be used to classify types of errors that occur, and can be used to react to errors.
error_description A specific error message that can help a developer identify the root cause of an authentication error.
error_uri A link to more detailed information about the error and how to resolve it.

The following table describes the various error codes that can be returned in the error parameter of the error response.

Error code Description
access_denied Resource owner denied consent.
invalid_request The request is missing a required parameter, includes an invalid parameter value, or is otherwise malformed.
unauthorized_client The client is not authorized to request an authorization code using this method.
unsupported_response_type The authorization server does not support obtaining an authorization code using this method.
server_error The authorization server encountered an unexpected condition which prevented it from fulfilling the request.
temporarily_unavailable The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.

6. Redeem code for access token
Having accessed the authorization code, you can now use that and a code_verifier to authenticate and redeem an access_token. Submit a POST or GET request to /auth/token with grant_type=authorization_code.

Endpoint documentation: Getting an access_token with authorization code.

Example request

curl --silent --show-err --data code=xxx -d grant_type=authorization_code
  -d client_id=1234 -d code_verifier=abc  -d redirect_uri=http://app.com/landing
  https://api.monerium.dev/auth/token

9-10. Refreshing the access token
Access tokens are short lived and you must refresh them after they expire to continue accessing resources. You can do so by submitting another POST or GET request to the /auth/token endpoint, this time providing the refresh_token instead of the code.

Endpoint documentation: Getting an access_token with a refresh_token.

Client credentials authorization

Confidential clients which can hide their credentials, e.g. backend servers, can be enlisted in Monerium's partner program, which enables them simultaneous access to multiple profiles which have granted authorization. These clients can get an access_token by submitting a POST or GET request to /auth/token:

 curl --location --request POST 'http://api.monerium.app/auth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=1234567890abcdef' \
--data-urlencode 'client_secret=27b871f28ab834b6be75c21578b4c944527fe34fce3952dc59f9c928b8502ee8' \
--data-urlencode 'grant_type=client_credentials'

Endpoint documentation: Getting an access_token with client credentials.


Profiles

Customers are represented by profiles whose identifier is the profile ID. The profile kind is used to differentiate between personal profiles and corporate profiles. All resources, such as orders, are owned by a profile. Users and external applications can be associated with profiles which grants them access to the resources owned by the profile. Usually there is a 1-to-1 relationship between a user and a personal profile but often there is a many-to-one relationship or many-to-many relationship between users and corporate profiles, where a single user may have access to multiple corporate profiles and multiple users may have access to a single corporate profile.

Partners configure an application which requests access to profiles and upon approval from a user, who is authorized to grant access to the profile, the application may perform actions on resources owned by the profile.

Overview

Action Endpoint
Retrieving a single profile /profiles/{profileId}
Retrieving balances for a single profile /profiles/{profileId}/balances
Retrieving orders for a single profile /profiles/{profileId}/orders
Place order for profile /profiles/{profileId}/orders
Subscribe to order notifications /profiles/{profileId}/orders
Linking a wallet to a profile. /profiles/{profileId}/addresses

Orders

Orders manage the lifecycle of the emoney. As such an order is created when new emoney is issued and when it is redeemed, and they contain information about the currency, amount, and the blockchain address. In addition information about the payer (for issue orders) beneficiary (for redeem order) is available as the counterpart.

Order states

Orders can be in one of the following states:

State Description
placed The order has been created, but payment has not been received.
pending The order is being processed by Monerium.
processed The order has been processed successfully (approved).
rejected The order could not be processed by Monerium. The rejected reason is documented in the order rejectedReason field.

Order notifications

API consumers can either poll the orders endpoint periodically or subscribe to a websocket for order notifications. The websocket adheres to the standard WebSocket Protocol and familiar websocket libraries can be used to subscribe to them. For testing purposes the wscat utility can come in handy.

$ npm install -g wscat
$ wscat --auth <email>:<password> -c wss://api.monerium.dev/orders

The websocket server will periodically send a PING control frame, to which the websocket consumer must respond with a PONG control frame. In the case the PONG is not sent in a timely manner the websocket server will close the connection to preserve resources. Many libraries handle this logic for the developer.

The websocket will emit the same order three times, once for the following state changes:

  1. placed - the initial state
  2. pending - money has been received for issue orders or tokens have been burnt for redeem orders.
  3. processed - the final state

Overview

Action Endpoint
Place order. /orders
Retrieve all orders /orders
Retrieve a single order. /orders/{orderId}
Subscribe to order notifications. /orders
Upload supporting documents /files/supporting-documents

Environments

Monerium maintains several execution environments which may differ in features and availability guarantees. Each API environment comes with a web client which can be used during integration to visualize the data provided by the API.

Production

Environment which targets a production blockchain involving real emoney.

Base URL api.monerium.app
Web client monerium.app
Availability Stable environment, publicly available
Features May be lagging behind other environments

Sandbox

Environment which targets a test blockchain involving fake emoney.

Base URL api.monerium.dev
Web client sandbox.monerium.dev
Availability Stable environment, publicly available
Features Parity with production environment while simulating periphery services

Identifiers and time formats

Identifiers

Identifiers are used to identify resources and actors. All identifiers used by the API are Universally Unique Identifiers (UUID) on the form 123e4567-e89b-12d3-a456-426614174000. The UUID 00000000-0000-0000-0000-000000000000 is a special identifier reserved for the Monerium System. This essentially means that an automation was performed by the system.

Datetime

Dates are formatted according to RFC 3339, with sub-second precision, unless otherwise specified. Example date: 2021-02-13T16:41:10:091Z. The Z at the end is a suffix which denotes a UTC offset of 00:00; often spoken “Zulu”.