API Structure
Domains
Mediobanca Premier exposes its Production APIs on external-api.mediobancapremier.io domain. The APIs exposed here are protected by OAuth2.0 authentication.
If you want to use our API Sandbox, you must use sandbox-api.mediobancapremier.io domain.
REST API - Naming & Methods
In Mediobanca Premier, we decided to follow the REST principles to define our APIs. It means that we identified some entities, the resources, on which we execute some actions.
The resources we identified are:
- customer, identified by the customerId (numeric format)
- product, identified by the productId (with product, we mean a bank account of any type) (alphanumeric format, 10 characters length)
- transaction resource, identified by the resourceId (this is a "temporary" resource, which represents an operation to execute, and it's disposed after the operation is finished) (UUID format) Then, you'll see these resources specified in every URL of our APIs.
In the REST specification, there are some operations that can be executed on each resource, identified by the HTTP methods; instead we chose to relax the REST paradigm a little, so we currently use only one HTTP method for each endpoint, and we use additional path parts to specify the action to execute on the resource.
E.g. In a standard REST approach, a GET API on the product resource (GET /private/customers/{customerId}/products/{productId}) should return both the balance AND the transactions information (and potentially other information too).
Instead we have more than one API retrieving data about the customer accounts, so, for example:
- GET /private/customers/{customerId}/products/{productId}/balance/retrieve → returns only the balance of the account
- GET /private/customers/{customerId}/products/{productId}/transactions/retrieve → returns only the transaction list for the specified account
However, we preserved the original HTTP verbs meaning, in fact we use:
- GET for the inquiry APIs
- POST to create a resource
- PUT to modify a resource
- DELETE to delete a resource
All the API endpoints start with a prefix, which identifies the security realm:
- /private → it means the API is protected, and needs the login security token to be executed
- /public → it means the API can be executed without the customer authentication
An example of some API endpoints:
- GET /private/customers/{customerId} → this API returns the customer details
- GET /private/customers/{customerId}/products → this API returns the customer account list
- GET /private/customers/{customerId}/products/{productId} → this API returns the details for a customer account
- POST /private/customers/{customerId}/products/{productId}/moneyTransfer/verify → this API accepts the parameters for a bank transfer and creates a transaction resource on our systems
Body format
We support the application/json content type, both for the requests and for the responses.
Headers & Cookies
To call Mediobanca Premier APIs, you need to pass some additional headers. The following table shows the headers needed by every API:
Header name | Value | Description |
---|---|---|
Accept-Language | A standard value for this header | (optional) to define what language will the response be written in |
CB-Trace-Id | viewId=< COMPONENT_NAME > | (optional) It contains the information about the "component" of the application calling the API; it's in the format viewId=< COMPONENT_NAME >, where COMPONENT_NAME can be a widget name, a webview identifier, etc. Used only for troubleshooting purposes |
Content-Type | application/json | |
Accept | application/json | |
Authorization | Bearer < TOKEN > | it contains the OAuth2 security token (the TOKEN is in the UUID standard format, 8-4-4-4-12 hex characters) |
cb-apitrack-id | < GENERATED_ID > | (optional) it contains a unique identifier of the application session, used only for tracing and troubleshooting purposes. This header is server-generated and returned by the first HTTP call to a mediobancapremier.io endpoint. The caller application must keep this value and pass it back and forth to every API call belonging to the same application session. |
TPP-Transaction-ID | < UUID VALUE > | ID of the transaction as determined by the initiating party (TPP). It should be used in every call involved in the same transaction. It must be an Universal Unique Identifier (UUID) |
TPP-Request-ID | < UUID VALUE > | ID of the request, unique to the call, as determined by the initiating party (TPP). It must be an Universal Unique Identifier (UUID). |
Signature | < GENERATED_VALUE > | Signature header of the request, as defined by draft-cavage-http-signatures-09. |
PSU-IP-Address | < SOURCE_IP_ADDRESS > | Used to forward the IP Address of the final user (PSU) from the original session between PSU and TPP. |
Digest | < SHA256_VALUE> | SHA256 of the body, as defined by draft-cavage-http-signatures-09. The header is NOT mandatory if request HTTP method is GET. |
Date | < DATE > | Date and time of the request, formatted as HTTP-Date defined by RFC 7231 in section 7.1.1.2 (Example: Tue, 15 Nov 2018 08:12:31 GMT). |
Response status codes
Our APIs will return the following HTTP status codes:
HTTP code | HTTP description | Notes |
---|---|---|
200 | OK | |
204 | No Content | |
302 | Found | Returned only by few specific APIs, in particular those to obtain an OAuth access token |
400 | Bad Request | |
401 | Unauthorized | In case the security token passed is not valid |
403 | Forbidden | Returned in case of a client not allowed to call a specific API |
412 | Precondition failed | Returned in case of a failure in the retrieval of some backend data based on some input parameter |
417 | Expectation failed | Returned in case of an error in the formal validation of the request |
420 | Enhance your calm | API call exceeded for a client in a defined interval of time |
422 | Unprocessable entity | The request contains special not allowed characters |
500 | Internal server error | Generic server error |
HAL links
We implement the HAL specification (http://stateless.co/hal_specification.html) with some limitations:
- the _links structure contains only self and next element, besides the curies structure
- the _embedded structure contains an arbitrary number of elements representing an API (composed of HTTP method and href)
- the _embedded structure is not "recursive", so no element can contain another _links structure
Response structure
The majority of our API responses are compliant with the following JSON structure; the only exceptions are the APIs which return a binary content.
{
"result": {
"messages": [{
"code": "<API_RETURN_CODE>",
"message": "<API_RETURN_MESSAGE>",
"type": "<SUCCESS|INFO|ERROR|WARNING>",
"detail": "<API_DETAILED_RETURN_MESSAGE>"
}],
"flushMessages": true,
"outcome": "<SUCCESS|ERROR>",
"requestId": "<REQUEST_UNIQUE_ID>"
},
"data": {
...<SPECIFIC_API_RESPONSE_DATA>...
},
"resources": {
"resourceId": "<TRANSACTION_RESOURCE_ID>"
},
"_links": {
"next": {
"href": "<RELATIVE_PATH>",
"method": "<METHOD>"
},
"self": {
"href": "<RELATIVE_PATH>",
"method": "<METHOD>"
},
"curies": [{
"href": "<BASE_LINKS_PATH>",
"name": "<OPERATION_NAME>"
}]
},
"_embedded": {
"<EMBEDDED_NAME_1>": {
"href": "<ABSOLUTE_PATH>",
"method": "<METHOD>"
},
"<EMBEDDED_NAME_N>": {
"href": "<ABSOLUTE_PATH>",
"method": "<METHOD>"
}
}
}
Attribute name | Description |
---|---|
messages | It's an array; every API can return more than a message, with different outcome levels (SUCCESS, INFO, WARNING, ERROR) |
API_RETURN_CODE | The alphanumeric string which describes the outcome; populated both in success and in failure outcomes |
API_RETURN_MESSAGE | A descriptive message of the outcome |
API_DETAILED_RETURN_MESSAGE | An additional, more detailed, descriptive message of the outcome |
REQUEST_UNIQUE_ID | Unique ID of the API request, used for troubleshooting purposes |
SPECIFIC_API_RESPONSE_DATA | The JSON structure with the specific API response data |
TRANSACTION_RESOURCE_ID | (populated in case of a POST call creating a transaction resource) UUID that represents the resource just created |
_links | HAL structure; it can contain: - the self element (always) - the next element (if expected) - the curies element (always) → it contains the name and the base path of the APIs involved in the operation executing |
RELATIVE_PATH | Relative path of the self/next API in the flow, starting from the curies.href |
METHOD | HTTP method to use to call the self/next API |
BASE_LINKS_PATH | Base path of the group of APIs implementing the operation (e.g. for the bank transfer executions, BASE_LINKS_PATH = https://external-api.mediobancapremier.io/private/customers/{customerId}/products/{productId}/moneyTransfer/{rel} {rel} corresponds to the href of the self/next element |
OPERATION_NAME | Name of the operation implemented by this API |
_embedded | HAL structure that contains other APIs callable after the current API. We interpreted the embedded elements as parallel flows to the main operation flow (e.g. API to retrieve a PDF for an operation, the 2-factor authentication flow, etc, that are not part of the implementation of a bank operation, but that are related to it in some way) |
EMBEDDED_NAME_N | Symbolic name of the embedded element |
ABSOLUTE_PATH | Absolute path of the API |
METHOD | HTTP method to use to call the embedded API |