Introduction
Welcome to Januar API! You can use our API to automate access to your payment accounts with Januar.
Swagger / OpenAPI
The Januar API also exist as Swagger UI and it's underlying OpenAPI specification which is available here
Environments
Januar provides two distinct environments available to the public:
Environment name | Base URL | Description |
---|---|---|
UAT | https://api.test.januar.com |
Used for testing integrations |
Production | https://api.januar.com |
Live production environment |
Message format
The Januar API uses JSON for both HTTP request and response payloads.
Success responses
Success response example where primary data is an object
{
"data": {
// ...
},
"metadata": {}
}
Success response example for a list endpoint
{
"data": [
// ...
],
"metadata": {
"pagination": {
"pageSize": 100,
"page": 0,
"totalRecords": 1234
}
}
}
Whenever the API returns a success status code (2xx
), the response payload contains a JSON object
with the following format:
Field | Type | Description |
---|---|---|
data |
Object or Array | Primary data returned from the endpoint. |
metadata |
Object | Metadata about the response |
↳ pagination |
Object | (Optional) Pagination information, is defined in list endpoints. |
↳ pageSize |
Number | Maximum number of records returned per page in this response |
↳ page |
Number | Page number to retrieve, 0-indexed |
↳ totalRecords |
Number | Total number of records available |
Error responses
Error format example
{
"error": {
"code": "ACCOUNT_INSUFFICIENT_BALANCE",
"message": "Your account does not have sufficient balance to carry out this operation.",
"context": {
"requiredBalance": "123.45",
"availableBalance": "100.00",
"currency": "EUR"
}
},
"sessionId": "ABC123ABC1234"
}
Default error payload for
401 Unauthorized
{
"error": {
"code": "INVALID_AUTHENTICATION",
"message": "Authentication failed",
"context": {}
},
"sessionId": "ABC123ABC1234"
}
Default error payload for
404 Not Found
{
"error": {
"code": "NOT_FOUND",
"message": "The requested resource was not found",
"context": {}
},
"sessionId": "ABC123ABC1234"
}
Whenever the API returns an error status code (4xx
for client errors, 5xx
for server errors),
the response payload contains a JSON object with the following format (See example to the right):
Field | Type | Description |
---|---|---|
error |
Object | Object describing the error that occurred. |
↳ code |
String | Machine-readable error code. |
↳ message |
String | Human-friendly error message. |
↳ context |
Object | Additional information related to the error. Object structure depends on the error code . Empty object if nothing. |
sessionId |
String | (Optional) session ID (also known as correlation ID) for the action. null if error occurred in such a way that an ID could not be generated (never expected to happen). |
The Januar API uses the following HTTP error codes:
Error Code | Meaning |
---|---|
400 Bad Request |
Bad Request -- Your request is invalid. |
401 Unauthorized |
Unauthorized -- Your authentication details are invalid. See Authentication section for more information |
403 Forbidden |
You are not allowed to access the specified resource. |
404 Not Found |
The specified resource could not be found. |
500 Internal Server Error |
We had a problem with our server. Try again later. |
503 Service Unavailable |
We're temporarily offline for maintenance. Please try again later. |
Common data types
This section lists common data types that will be used throughout the API:
Amount
All amounts are decimal numbers encoded as strings to avoid implicit precision errors when encoding/decoding the amounts.
An example is "203.10"
.
Precision
All FIAT amounts are represented with a precision of 2 decimal places.
All crypto amounts are represented with a variable precision dependent on asset type (see below).
Country
All countries are represented by their * ISO 3166-1 alpha-2 country code*.
Examples include "DE"
for Germany, and "DK"
for Denmark.
Currency
All fiat currencies are represented by their ISO 4217 currency code.
Examples include "EUR"
for Euro, and "DKK"
for Danish Krone.
IBAN
IBANs (International Bank Account Number) are defined in the ISO 13616 standard (Wikipedia IBAN page).
An example of a Danish IBAN is "DK8589000099106422"
.
BIC code
BICs (Business Identifier Code) are represented by their * ISO 9362 code*.
An example of a Danish BIC is "SXPYDKKKXXX"
.
Timestamp
All timestamps are represented by a *ISO 8601 timestamp *.
An example is "2022-09-05T09:28:36Z"
, meaning the timestamp 09:28:36 (UTC timezone) on September
5th, 2022.
Timestamps may include millisecond precision where applicable: "2022-09-05T09:28:36.420Z"
AssetType
All asset types are represented by a string.
The following asset types are supported:
"ETH"
: Ethereum, decimal precision: 18 positions- '"BTC"': Bitcoin, decimal precicion: 8 positions
- '"USDC"': USDC, decimal precision: 6 positions
Authentication
Example
Authorization
header:
Authorization: JanuarAPI apikey="e871abb0-8a8d-4f6a-8551-7d34927af641", nonce="1660895358165", signature="oEp4bQXaYnRWG2XrbGfqeuGPEef6fokPjq9mA+gzBbE="
You must obtain an API key and secret pair to access our API. This key and secret pair must be used in the construction of every HTTP request to authenticate towards our API.
In order to authenticate an HTTP request, it must include the following information in the Authorization
HTTP header:
apikey
: API keynonce
: An integer that must increase with every successful request. It's common to use current Unix timestamp with millisecond precision for this.signature
:HMAC-SHA256
signature of request using API secret as key, encoded using base64
Signature generation
To generate a valid
Authorization
header, use this code:
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
String method="POST";
String accountId="cd74be8b-9f34-456e-86ee-15fa46a2a8b7";
String path=URLEncoder.encode("/accounts/"+accountId+"/transactions/payout","UTF-8");
String payload="{\"amount\": \"12.45\", \"currency\": \"DKK\", \"iban\": \"LU044080000020017267\", \"paymentTime\": \"2023-05-25T11:43:00Z\", \"message\": \"Transfer to Acme customer\", \"name\": \"James Robert\", \"internalNote\": \"message to myself\"}";
String apiKey="e871abb0-8a8d-4f6a-8551-7d34927af641";
String apiSecret="d39e5f5d-281e-4917-a878-8392dedaaf55";
SecretKeySpec secretKey=new SecretKeySpec(apiSecret.getBytes("UTF-8"),"HmacSHA256");
long nonce=1660895358165L; // // Use System.currentTimeMillis() to get current Unix timestamp
String messageToSign=nonce+"|"+method+"|"+path+"|"+payload;
Mac sha256_HMAC=Mac.getInstance("HmacSHA256");
sha256_HMAC.init(secretKey);
String signature=new String(Base64.encodeBase64(sha256_HMAC.doFinal(messageToSign.getBytes("UTF-8"))));
String authHeader="Authorization: JanuarAPI apikey=\""+apiKey+"\", nonce=\""+nonce+"\", signature=\""+signature+"\"";
System.out.println(authHeader);
// Outputs:
// Authorization: JanuarAPI apikey="e871abb0-8a8d-4f6a-8551-7d34927af641", nonce="1660895358165", signature="3hhU/isW55nkONRRi0rPoBwv6+MP0LDtIkgXLCxeiRI="
import crypto from 'crypto';
const method = 'POST';
const accountId = 'cd74be8b-9f34-456e-86ee-15fa46a2a8b7'
const path = encodeURIComponent(
'/accounts/' + accountId + '/transactions/payout');
const payload = JSON.stringify(
{
"amount": "12.45",
"currency": "DKK",
"iban": "LU044080000020017267",
"paymentTime": "2023-05-25T11:43:00Z",
"message": "Transfer to Acme customer",
"name": "James Robert",
"internalNote": "message to myself"
});
const apiKey = 'e871abb0-8a8d-4f6a-8551-7d34927af641';
const apiSecret = 'd39e5f5d-281e-4917-a878-8392dedaaf55';
const nonce = 1660895358165; // Use Date.now() to get current Unix timestamp
const messageToSign = nonce + '|' + method + '|' + path + '|' + payload;
const signature = crypto.createHmac('sha256', apiSecret).update(messageToSign).digest('base64');
const authHeader = `Authorization: JanuarAPI apikey="${apiKey}", nonce="${nonce}", signature="${signature}"`;
// Outputs:
// Authorization: JanuarAPI apikey="e871abb0-8a8d-4f6a-8551-7d34927af641", nonce="1660895358165", signature="3hhU/isW55nkONRRi0rPoBwv6+MP0LDtIkgXLCxeiRI="
console.log(authHeader);
import base64
import hmac
import json
import time
import urllib.parse
from hashlib import sha256
method = 'POST'
account_id = 'cd74be8b-9f34-456e-86ee-15fa46a2a8b7'
path = '/accounts/' + account_id + '/transactions/payout'
encoded_path = urllib.parse.quote(path, safe='')
payload = {
"amount": "12.45",
"currency": "DKK",
"iban": "GB15CLYD82663220400952",
"paymentTime": "2023-05-25T11:43:00Z",
"message": "Transfer to Acme customer",
"name": "James Robert",
"internalNote": "message to myself"
}
api_key = "e871abb0-8a8d-4f6a-8551-7d34927af641"
api_secret = "d39e5f5d-281e-4917-a878-8392dedaaf55"
nonce = 1660895358165 # use int(time.time() * 1000) for current Unix timestamp
message_to_sign = f"{nonce}|{method}|{encoded_path}|{json.dumps(payload)}".encode(
"utf-8")
sha256_HMAC = hmac.new(api_secret.encode("utf-8"), message_to_sign,
digestmod=sha256)
signature = base64.b64encode(sha256_HMAC.digest()).decode()
auth_header = f'Authorization: JanuarAPI apikey="{api_key}", nonce="{nonce}", signature="{signature}"'
print(auth_header)
# Output
# Authorization: JanuarAPI apikey="e871abb0-8a8d-4f6a-8551-7d34927af641", nonce="1660895358165", signature="3Cr1HxM7ZNnAIFNehJ4FLbbHPvFFdE0xi8cFJ4tGiOE="
Make sure to replace
apiKey
andapiSecret
with your API key and secret pair.
A valid request signature signs over the following parts of an HTTP request:
- Nonce
- Method:
GET
,POST
, etc - Path including query string:
e.g.
/accounts/340975fd-fc40-4011-8f21-c8d6abd4a124/transactions?page=0&pageSize=1000
- Body: e.g.
{"action":"pay"}
. If the request does not have a body, an empty string is used.
The signature is a HMAC-SHA256 of the concatenation of the nonce, method (uppercased), path (including query string) and body (if no body, empty string), separated by pipe character (|
), using the API secret as signing key, encoded with base64.
Authentication error
Authentication error object (HTTP status code will be
401 Unauthorized
)
{
"code": "IDENTITY_ACCESS_MANAGEMENT_CUSTOMER_UNAUTHORIZED",
"message": "Customer is not authorized to access this resource",
"context": {}
}
In case the Authorization
header is missing, api key doesn't exist, or the signature validation fails, any request will fail with a 401 Unauthorized
HTTP status code.
Accounts
Terminology
This section aims to provide a high-level overview of the different entities and concepts in the Accounts API
Concept | Description |
---|---|
Account | An account holds your balances in one or more currencies. |
Balance | A balance is the amounts of available money in a single currency of a given account. |
Transaction | A transaction in its basic form represents a group of account movements happening as one unit. It is specialized in multiple different sub types detailing individual interactions that can happen on your account, e.g. a payout (See Types of transactions below). |
Types of transactions
Type | Description |
---|---|
Payin | A payin transaction is when money is received in your account from an external account. |
Returned payin | A returned payin transaction is when a previously received payin transaction was returned to the sender. |
Payout | A payout transaction is when money is sent from your account to an external account. |
Returned payout | A returned payout transaction is when a previously sent payout transaction was returned to your account. |
Currency conversion | A currency conversion transaction is when you convert money from one currency in your account to another currency in the same account. |
Fee | A fee transaction is when your account is charged a stand-alone fee. |
Returned fee | A returned fee transaction is when a previously paid fee transaction was returned to your account. |
List accounts
Example
200 OK
response forGET /accounts
{
"data": [
{
"id": "f27cd81e-27ef-43fd-9aaf-22abe65dd0c7",
"name": "My account",
"status": "active",
"defaultCurrency": "EUR",
"currencies": {
"DKK": {
"balance": "1175023.15"
},
"EUR": {
"balance": "996225.43"
}
},
"accountNumbers": [
{
"iban": "DK8589000099106422",
"country": "DK",
"defaultCurrency": "EUR",
"bank": {
"name": "BANKING CIRCLE",
"bic": "SXPYDKKKXXX",
"address": [
{
"street": "Amerika Plads 38",
"zip": "2100",
"city": "København Ø",
"region": "Hovedstaden",
"country": "DK"
}
]
},
"bankIdentifier": "8900",
"accountNumber": "0099106422"
}
]
}
],
"metadata": {}
}
This endpoint retrieves all your accounts.
HTTP Request
GET /accounts
HTTP Response
200 OK
The endpoint returns a list of account objects
Get account
Example
200 OK
response forGET /accounts/:accountId
{
"data": {
"id": "f27cd81e-27ef-43fd-9aaf-22abe65dd0c7",
"name": "My account",
"status": "active",
"defaultCurrency": "EUR",
"currencies": {
"DKK": {
"balance": "1175023.15"
},
"EUR": {
"balance": "996225.43"
}
},
"accountNumbers": [
{
"iban": "DK8589000099106422",
"country": "DK",
"defaultCurrency": "EUR",
"bank": {
"name": "BANKING CIRCLE",
"bic": "SXPYDKKKXXX",
"address": [
{
"street": "Amerika Plads 38",
"zip": "2100",
"city": "København Ø",
"region": "Hovedstaden",
"country": "DK"
}
]
}
}
]
},
"metadata": {}
}
This endpoint retrieves an account.
HTTP Request
GET /accounts/:accountId
Path Parameters
Parameter | Description |
---|---|
accountId |
ID of the account to be retrived. |
HTTP Response
200 OK
The endpoint returns an account object
List transactions
This endpoint lists all transactions for a particular account, sorted by newest first.
Example
200 OK
response forGET /accounts/75db7319-d2fd-4610-98c2-201fbe49e6f3/transactions
{
"data": [
{
"id": "814b3ab1-b997-40a3-8c63-5593518fb619",
"accountId": "75db7319-d2fd-4610-98c2-201fbe49e6f3",
"type": "PAYOUT",
"currency": "EUR",
"status": "COMPLETED",
"amount": "-123.45",
"feeAmount": "-0.10",
"message": "Transfer to Acme customer",
"internalNote": "message to myself",
"counterparty": {
"name": "Januar Aps",
"accountNumber": "DE68500105178297336485",
"accountNumberType": "IBAN",
"accountNumberCountryCode": "DE"
},
"initiatedTime": "2022-08-17T11:31:43.868328Z",
"paymentTime": "2022-08-31T10:00:00Z"
},
{
// ... more transactions
}
],
"metadata": {
"pagination": {
"pageSize": 100,
"page": 0,
"totalRecords": 61
}
}
}
HTTP Request
GET /accounts/:accountId/transactions
Path Parameters
Parameter | Description |
---|---|
accountId |
ID of account to list transactions for. |
Query Parameters
Parameter | Default | Description |
---|---|---|
types |
[] |
If set, only return transactions of the given types |
pageSize |
100 |
Positive integer determining how many transactions to return per page, max 1000 |
page |
0 |
Page number to retrieve, 0-indexed |
statuses |
[] |
List of payout Payout statuses to query. As statuses only apply to payouts, adding a status filter to the query, will result in only payouts will be returned. If not provided, all types will be queried |
dateFrom |
null |
Determines the earliest transactionTime of the transactions queried. Format YYYY-MM-DD |
dateTo |
null |
Determines the latest transactionTime of the transactions queried. Format YYYY-MM-DD |
amountFrom |
null |
Determines the inclusive lower limit for the transaction amount |
amountTo |
null |
Determines the inclusive upper limit for the transaction amount |
currencies |
[] |
List of currencies code to query. If not provided, all transaction currencies will be queried |
text |
null |
Search term. Will query in following fields message , counterparty.accountNumber , counterparty.name , internalNote |
HTTP Response
200 OK
The endpoint returns a list of transactions
Possible errors
HTTP Status code | error.code |
Description | context |
---|---|---|---|
404 Not Found |
ACCOUNT_NOT_FOUND |
Account with ID :accountId not found on customer: :customerId |
None |
400 Bad Request |
BAD_REQUEST |
Invalid value: :value for field: :field |
None |
400 Bad Request |
BAD_REQUEST |
Type mismatch | None |
400 Bad Request |
CURRENCY_NOT_SUPPORTED |
Invalid currency: :currency |
None |
Get transaction
This endpoint retrieves a transaction for a particular account.
Example
200 OK
responsefor
GET /accounts/75db7319-d2fd-4610-98c2-201fbe49e6f3/transactions/814b3ab1-b997-40a3-8c63-5593518fb619
{
"data": {
"id": "814b3ab1-b997-40a3-8c63-5593518fb619",
"accountId": "75db7319-d2fd-4610-98c2-201fbe49e6f3",
"type": "PAYOUT",
"completedTime": "2023-03-26T01:00:08.806Z",
"currency": "EUR",
"status": "COMPLETED",
"amount": "-123.45",
"feeAmount": "0.00",
"message": "Transfer to Acme customer",
"internalNote": "message to myself",
"counterparty": {
"name": "Januar Aps",
"accountNumber": "DE68500105178297336485",
"accountNumberType": "IBAN",
"accountNumberCountryCode": "DE"
},
"initiatedTime": "2023-03-21T10:51:40.415604Z",
"paymentTime": "2023-03-26T11:51:40Z"
},
"metadata": {}
}
HTTP Request
GET /accounts/:accountId/transactions/:transactionId
Path Parameters
Parameter | Description |
---|---|
accountId |
ID of the account to list the transaction. |
transactionId |
ID of the transaction to be retrieved. |
HTTP Response
200 OK
The endpoint returns a transaction
Possible errors
HTTP Status code | error.code |
Description | context |
---|---|---|---|
404 Not Found |
ACCOUNT_NOT_FOUND |
Account with ID :accountId not found on customer: :customerId |
None |
400 Bad Request |
BAD_REQUEST |
Type mismatch | None |
Initiate payout
This endpoint enables you to initiate a single payout.
HTTP Request
POST /accounts/:accountId/transactions/payout
Example request for initiating a payout at
POST /accounts/:accountId/transactions/payout
{
"amount": "10.01",
"currency": "EUR",
"paymentTime": "2022-09-16T06:00:00Z",
"message": "Payment ref: #abcdef",
"internalNote": "Payment for goods",
"counterparty": {
"name": "Januar Aps",
"accountNumber": "DE68500105178297336485",
"accountNumberType": "IBAN",
"accountNumberCountryCode": "DE"
}
}
Path Parameters
Parameter | Description |
---|---|
accountId |
ID of account to initiate the payout for. |
Request body
Field | Type | Description |
---|---|---|
amount |
Amount | The amount of the payout. Note the fee amount will be visible on the initiated payout instance. |
currency |
Currency | Currency of the payout. |
paymentTime |
Timestamp | (Optional) The future timestamp of when this payout should happen. If not specified it should happen now. |
message |
String | Message to the receiver. |
internalNote |
String | (Optional) Note only visible to the creator of the payout. |
counterparty |
Counterparty | Counterparty information. |
↳ name |
String | Name of the receiver of this payout |
↳ accountNumber |
String | Account number of the reciever - this can be an IBAN(ISO 13616:2020) or BBAN |
↳ accountNumberType |
String | Type of the account number - either IBAN or BBAN |
↳ accountNumberCountryCode |
String | (Optional for IBANs) Country code of the account number |
HTTP Response
Example
201 Created
response from initiate payout
{
"data": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"accountId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"type": "PAYIN",
"completedTime": "2022-11-12T12:34:56Z",
"currency": "EUR",
"status": "PENDING",
"amount": "10.01",
"feeAmount": "0.51",
"message": "Payment ref: #abcdef",
"internalNote": "Payment for goods",
"initiatedTime": "2022-11-12T12:34:56Z",
"paymentTime": "2022-11-12T12:34:56Z",
"counterparty": {
"name": "Januar Aps",
"accountNumber": "DE68500105178297336485",
"accountNumberType": "IBAN",
"accountNumberCountryCode": "DE"
}
},
"metadata": {}
}
201 Created
The endpoint returns a payout transaction
Possible errors
HTTP Status code | error.code |
Description | context |
---|---|---|---|
400 Bad Request |
invalid-format |
There was a formatting error in the request. See error message for details. | None |
400 Bad Request |
invalid-iban |
Invalid IBAN specified. | None |
400 Bad Request |
insufficient-funds |
There is insufficient funds available on the account to initiate the payout. | requiredBalance : the required balance for the payoutavailableBalance : the available balancecurrency : currency for the balances |
400 Bad Request |
invalid-payment-time |
The paymentTime must be in the future. |
None |
400 Bad Request |
unsupported currency |
Specified currency is not supported by the account. | None |
404 Not found |
account-not-found |
Account with ID :accountId could not be found. |
None |
Cancel payout
Example request for cancelling a payout at
PUT /accounts/:accountId/transactions/payout/:payoutId/cancel
Example
200 OK
response from canceled payout
{
"data": {
"id": "67f8cbd2-166a-48b2-86e1-f0c46a426aa3",
"accountId": "3fa8bac8-e173-4d49-8f68-18ec2bd52b2a",
"type": "PAYOUT",
"currency": "EUR",
"status": "CANCELLED",
"amount": "-123.45",
"feeAmount": "-0.10",
"message": "Transfer to Acme customer",
"internalNote": "message to myself",
"initiatedTime": "2022-09-05T10:45:12Z",
"paymentTime": "2022-09-16T06:00:00Z",
"counterparty": {
"name": "Januar Aps",
"accountNumber": "DE68500105178297336485",
"accountNumberType": "IBAN",
"accountNumberCountryCode": "DE"
}
},
"metadata": {}
}
This endpoint enables you to cancel payouts.
HTTP Request
PUT /accounts/:accountId/transactions/payout/:payoutId/cancel
Path Parameters
Parameter | Description |
---|---|
accountId |
ID of account to initiate the payout for. |
payoutId |
ID of the payout to cancel |
Request body
The request body should be left empty
HTTP Response
200 OK
The endpoint returns a payout transaction with a
CANCELLED
status
Possible errors
HTTP Status code | error.code |
Description | context |
---|---|---|---|
404 Not Found |
ACCOUNT_NOT_FOUND |
Account with ID :accountId not found on customer: :customerId |
None |
404 Not Found |
PAYOUT_NOT_FOUND |
Payout with ID :payoutId could not be found. |
None |
400 Bad Request |
payout-not-cancelable |
The specified payout is not cancelable as it is in a final state | None |
400 Bad Request |
BAD_REQUEST |
Type mismatch | None |
Accounts data model
This section describes the data model of each type of entity in the Accounts API:
Account
Example account object
{
"id": "f27cd81e-27ef-43fd-9aaf-22abe65dd0c7",
"name": "My account",
"status": "active",
"defaultCurrency": "EUR",
"currencies": {
"DKK": {
"balance": "1175023.15"
},
"EUR": {
"balance": "996225.43"
}
},
"accountNumbers": [
{
"iban": "DK8589000099106422",
"country": "DK",
"defaultCurrency": "EUR",
"bank": {
"name": "BANKING CIRCLE",
"bic": "SXPYDKKKXXX",
"address": [
{
"street": "Amerika Plads 38",
"zip": "2100",
"city": "København Ø",
"region": "Hovedstaden",
"country": "DK"
}
]
},
"bankIdentifier": "8900",
"accountNumber": "0099106422"
}
]
}
An account holds your balances in one or more currencies.
Field | Type | Description |
---|---|---|
id |
String (UUID) | Unique identifier for the account |
name |
String | Name of account |
status |
String | Either ACTIVE or INACTIVE |
defaultCurrency |
Currency | Currency code for account's default currency. Always corresponds to a key in the currencies object. |
currencies |
Object | Map of currencies supported by the account. Each key is a supported currency. |
↳ currency |
Object | Single currency supported by the account. |
↳ balance |
String | Balance for specific currency in the account. |
accountNumbers |
Array | Account numbers associated with the account |
↳ [] |
Object | A single account number object |
↳ iban |
IBAN | IBAN (International Bank Account Number) |
↳ country |
Country | Country of account number |
↳ defaultCurrency |
Currency | Default currency of account number. |
↳ bank |
Bank | Bank providing the account number |
Transaction
Example transaction object of type
PAYIN
.Note that the
id
,accountId
,type
, andcompletedTime
fields are present for all types of transactions, while the rest of the fields are specific for thePAYIN
transaction type.
{
"id": "780e39f3-4fde-49c8-bd25-2ec2364fd01e",
"accountId": "3fa8bac8-e173-4d49-8f68-18ec2bd52b2a",
"type": "PAYIN",
"completedTime": "2022-08-15T11:45:32Z",
"currency": "EUR",
"amount": "123.45",
"feeAmount": "-0.10",
"message": "Transfer from Acme customer",
"counterparty": {
"name": "Januar Aps",
"accountNumber": "DE68500105178297336485",
"accountNumberType": "IBAN",
"accountNumberCountryCode": "DE"
}
}
A transaction in its basic form represents a group of account movements happening as one unit. It is specialized in multiple different sub types detailing individual interactions that can happen on your account, e.g. a payout.
A transaction has a number of base fields which are always included for any transaction type, as well as a number of fields which are type-specific. The base fields are defined first, and subsequently each specific transaction type is documented:
Field | Type | Description |
---|---|---|
id |
String (UUID) | Unique identifier for the transaction. |
accountId |
String (UUID) | Reference to the account that this transaction belongs to. |
type |
String | Type of transaction. This value should be used to determine which type-specific fields are included. See transaction types below. |
completedTime |
Timestamp | (Optional) Timestamp when the transaction was completed. |
Transaction types
For a brief overview of the different transaction types, please refer to the terminology section above.
type |
Transaction type |
---|---|
PAYIN |
Payin |
RETURNED_PAYIN |
Returned Payin |
PAYOUT |
Payout |
RETURNED_PAYOUT |
Returned Payout |
CURRENCY_CONVERSION |
Currency conversion |
FEE |
Fee |
RETURNED_FEE |
Returned Fee |
Payin transaction (PAYIN
)
Example payin transaction object
{
"id": "314b54a3-eb06-4dba-9032-9c06618763aa",
"accountId": "3fa8bac8-e173-4d49-8f68-18ec2bd52b2a",
"type": "PAYIN",
"completedTime": "2022-08-15T11:45:32Z",
"currency": "EUR",
"amount": "123.45",
"feeAmount": "-0.10",
"message": "Transfer from Acme customer",
"counterparty": {
"name": "Januar Aps",
"accountNumber": "DE68500105178297336485",
"accountNumberType": "IBAN",
"accountNumberCountryCode": "DE"
}
}
A payin transaction is when money is received in your account from an external account. The account
balance increases with the amount specified in the amount
field (subtracted an
optional feeAmount
).
Field | Type | Description |
---|---|---|
currency |
Currency | Currency code for this payin |
amount |
Amount | Positive amount indicating the money received in the account. |
feeAmount |
Amount | Zero or negative amount indicating the amount deducted as a fee of this transaction. |
message |
String | Free-text description from the sender. |
counterparty |
Counterparty | Counterparty information. |
↳ name |
String | Name of the receiver of this payout |
↳ accountNumber |
String | Account number of the reciever - this can be an IBAN(ISO 13616:2020) or BBAN |
↳ accountNumberType |
String | Type of the account number - either IBAN or BBAN |
↳ accountNumberCountryCode |
String | (Optional for IBANs) Country code of the account number |
Returned Payin transaction (RETURNED_PAYIN
)
Example returned payin transaction object
{
"id": "c16f5074-132b-4d41-b5d7-c7ffdb8217e6",
"accountId": "3fa8bac8-e173-4d49-8f68-18ec2bd52b2a",
"payinId": "314b54a3-eb06-4dba-9032-9c06618763aa",
"type": "RETURNED_PAYIN",
"completedTime": "2022-08-15T11:45:32Z",
"currency": "EUR",
"amount": "-123.45",
"feeAmount": "0.10"
}
A returned payin transaction is when a previously received payin transaction was returned to the sender.
Field | Type | Description |
---|---|---|
payinId |
String (UUID) | Id of the original payin transaction that this transaction returns. |
currency |
Currency | Currency code for this returned payin |
amount |
Amount | Negative amount indicating the money subtracted from the account. |
feeAmount |
Amount | Zero or positive amount indicating the amount added to the account. |
Payout transaction (PAYOUT
)
Example payout transaction object
{
"id": "67f8cbd2-166a-48b2-86e1-f0c46a426aa3",
"accountId": "3fa8bac8-e173-4d49-8f68-18ec2bd52b2a",
"type": "PAYOUT",
"completedTime": "2022-08-15T11:45:32Z",
"paymentTime": "2022-08-15T11:40:12Z",
"initiatedTime": "2022-08-15T11:40:12Z",
"currency": "EUR",
"status": "COMPLETED",
"amount": "-123.45",
"feeAmount": "-0.10",
"message": "Transfer to Acme customer",
"internalNote": "message to myself",
"counterparty": {
"name": "Januar Aps",
"accountNumber": "DE68500105178297336485",
"accountNumberType": "IBAN",
"accountNumberCountryCode": "DE"
}
}
A payout transaction is a payout from the account to an external account. The account balance
decreased with the amount specified in the amount
field (including an optional feeAmount
).
Field | Type | Description |
---|---|---|
currency |
Currency | Currency code for this payout |
status |
Payout status | Status of this payout |
amount |
Amount | Negative amount indicating the amount deducted from the account for this transaction. |
feeAmount |
Amount | Zero or negative amount indicating the fee amount deducted from the account. |
message |
String | Free-text message to the receiver. |
internalNote |
String | (Optional) Free-text internal note to oneself. |
counterparty |
Counterparty | Counterparty information. |
↳ name |
String | Name of the receiver of this payout |
↳ accountNumber |
String | Account number of the reciever - this can be an IBAN(ISO 13616:2020) or BBAN |
↳ accountNumberType |
String | Type of the account number - either IBAN or BBAN |
↳ accountNumberCountryCode |
String | (Optional for IBANs) Country code of the account number |
initiatedTime |
Timestamp | Timestamp of when the payout was initiated in the account. |
paymentTime |
Timestamp | Timestamp of when the payout was set to happen (payout can be delayed for some reason). |
Payout statuses
A PAYOUT
transaction can have the following status
codes:
Status code | Description | Final state? |
---|---|---|
AWAITING_CONFIRMATION |
The payout is awaiting confirmation from initiator. Only used when initiating from the web interface | No |
AWAITING_APPROVAL |
The payout is awaiting approval from an approver | No |
PENDING |
The payout is pending completion | No |
CANCELLED |
The payout was cancelled before it could complete | Yes |
REJECTED |
The payout was rejected | Yes |
COMPLETED |
The payout was successfully executed | Yes |
Returned Payout transaction (RETURNED_PAYOUT
)
Example returned payout transaction object
{
"id": "158315d3-3263-4906-839d-b755ef13498a",
"accountId": "3fa8bac8-e173-4d49-8f68-18ec2bd52b2a",
"payoutId": "67f8cbd2-166a-48b2-86e1-f0c46a426aa3",
"type": "RETURNED_PAYOUT",
"completedTime": "2022-08-15T11:45:32Z",
"currency": "EUR",
"amount": "123.45",
"feeAmount": "0.10"
}
A returned payout transaction is when a previously sent payout transaction was returned to your account.
Field | Type | Description |
---|---|---|
payoutId |
String (UUID) | Id of the original payout transaction that it returns. |
currency |
Currency | Currency code for this payout |
amount |
Amount | Positive amount indicating the amount added to the account as part of this returned payout. |
feeAmount |
Amount | Zero or positive amount indicating the fee amount returned as part of this returned payout. |
Currency conversion transaction (CURRENCY_CONVERSION
)
Example currency conversion transaction object
{
"id": "0223f4bd-3072-4387-9c46-b9f927ee756c",
"accountId": "3fa8bac8-e173-4d49-8f68-18ec2bd52b2a",
"type": "CURRENCY_CONVERSION",
"completedTime": "2022-08-15T11:45:32Z",
"sellCurrency": "EUR",
"sellAmount": "-1000.00",
"sellRate": "7.44123",
"buyCurrency": "DKK",
"buyAmount": "7441.23"
}
A currency conversion transaction is when you convert money from one currency (the sell currency) in your account to another currency (the buy currency) in the same account.
Field | Type | Description |
---|---|---|
sellCurrency |
Currency | Currency code of the sell amount. |
sellAmount |
Amount | Negative amount indicating the amount deducted from the account. |
sellRate |
String | Rate of the currency conversion. |
buyCurrency |
Currency | Currency code of the buy amount. |
buyAmount |
Amount | Positive number indicating the buy amount added to the account. |
Fee transaction (FEE
)
Example fee transaction object
{
"id": "d4450c67-80a1-4244-9ed3-9ae07aa7c686",
"accountId": "3fa8bac8-e173-4d49-8f68-18ec2bd52b2a",
"type": "FEE",
"completedTime": "2022-08-15T11:45:32Z",
"currency": "EUR",
"amount": "-99.90",
"message": "Acme monthly subscription fee"
}
A fee transaction is when your account is charged a stand-alone fee.
Field | Type | Description |
---|---|---|
currency |
Currency | Currency code for this fee. |
amount |
Amount | Negative amount indicating the amount deducted from the account from this fee transaction. |
message |
String | Message describing the fee to the receiver. |
Returned Fee transaction (RETURNED_FEE
)
Example returned fee transaction object
{
"id": "f3507542-edcf-4e8a-959d-3771fef2a380",
"accountId": "3fa8bac8-e173-4d49-8f68-18ec2bd52b2a",
"feeId": "90aac3f6-584b-4d3e-9d9c-a6c1332c74f5",
"type": "RETURNED_FEE",
"completedTime": "2022-08-15T11:45:32Z",
"currency": "EUR",
"amount": "99.90"
}
A returned fee transaction is when a previously paid fee transaction was returned to your account.
Field | Type | Description |
---|---|---|
feeId |
String (UUID) | Id of the fee transaction that it returns. |
currency |
Currency | Currency code for this fee. |
amount |
Amount | Positive amount indicating the amount added to the account because of this returned fee transaction. |
Bank
Example bank object
{
"name": "BANKING CIRCLE",
"bic": "SXPYDKKKXXX",
"address": {
"street": "Amerika Plads 38",
"zip": "2100",
"city": "København Ø",
"region": "Hovedstaden",
"country": "DK"
}
}
A reference to a bank.
Field | Type | Description |
---|---|---|
name |
String | Bank name |
bic |
BIC | BIC (Business Identifier Code) for bank |
address |
Address | Bank address |
Address
Example address object
{
"street": "Gothersgade 14",
"zip": "1123",
"city": "København",
"region": "Hovedstaden",
"country": "DK"
}
A reference to a physical address.
Field | Type | Description |
---|---|---|
street |
String | Street address |
zip |
String | (Optional) Zip code |
city |
String | City |
region |
String | (Optional) Region country |
country |
Country | Country code. |
Crypto
Terminology
This section aims to provide a high-level overview of the different entities and concepts in the Crypto API
Concept | Description |
---|---|
Wallet | A wallet is a collection of crypto assets and withdrawal addresses. |
Asset | An asset holds the amount available of a given crypto currency and its given deposit address. |
Withdrawal address | A withdrawal address is a whitelisted external crypto address not managed by Januar which can be used to withdraw assets to. This means that in order to withdraw funds to a an external address, you need to create a withdrawal address beforehand, otherwise the withdrawal will be blocked by Januar. Read more details in the withdrawal address section |
Crypto transaction | A crypto transaction is a INGOING or OUTGOING transfer of crypto assets. |
List wallets
Example
200 OK
response forGET /wallets
{
"data": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "My wallet",
"assets": [
{
"assetType": "ETH",
"balance": "0.1",
"depositAddress": "0x1234567890"
}
],
"withdrawalAddressTimeLockInMillis": 259200,
"withdrawalAddresses": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"label": "My Ether Wallet",
"initiated": "2023-03-20T12:39:44.177Z",
"validFrom": "2023-03-23T12:39:44.177Z",
"destinationAddress": "0x1234567890abcdef1234567890abcdef12345678",
"assetType": "ETH",
"status": "ACTIVE"
}
]
}
],
"metadata": {}
}
This endpoint returns a wallet.
HTTP Request
GET /wallets/
HTTP Response
The endpoint returns a list of wallet objects.
Get wallet
Example
200 OK
response forGET /wallets/3fa85f64-5717-4562-b3fc-2c963f66afa6
{
"data": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "My wallet",
"assets": [
{
"assetType": "ETH",
"balance": "0.1",
"depositAddress": "0x1234567890"
}
],
"withdrawalAddressTimeLockInMillis": 259200,
"withdrawalAddresses": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"label": "My Ether Wallet",
"initiated": "2023-03-20T12:39:44.177Z",
"validFrom": "2023-03-23T12:39:44.177Z",
"destinationAddress": "0x1234567890abcdef1234567890abcdef12345678",
"assetType": "ETH",
"status": "ACTIVE"
}
]
},
"metadata": {}
}
This endpoint returns a list of all your wallets.
HTTP Request
GET /wallets/:walletId
HTTP Response
200 OK
The endpoint returns a wallet object.
Submit withdrawal address
Example request for submitting a withdrawal address at POST /wallets/: walletId/withdrawal-addresses
{
"label": "My Ether Wallet",
"destinationAddress": "0x1234567890abcdef1234567890abcdef12345678",
"assetType": "ETH"
}
Example
201 Created
response from submit withdrawal address
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"label": "My Ether Wallet",
"initiated": "2023-03-20T12:39:44.177Z",
"validFrom": null,
"destinationAddress": "0x1234567890abcdef1234567890abcdef12345678",
"assetType": "ETH",
"status": "INITIATED"
}
This endpoints allows you to submit a withdrawal address for a given wallet.
HTTP Request
POST /wallets/:walletId/withdrawal-addresses
Path Parameters
Parameter | Type | Description |
---|---|---|
walletId |
UUID | ID of wallet to add and submit withdrawal address for |
Request Body
Parameter | Type | Description | Validation rules |
---|---|---|---|
label |
String | Label for withdrawal address | required |
destinationAddress |
String | Destination address to withdraw to | required |
assetType |
AssetType | Asset type of the withdrawal address. | required |
HTTP Response
The endpoint returns a withdrawal address object.
Possible errors
HTTP Status code | Error Code | Description | context |
---|---|---|---|
400 Bad Request |
VALIDATION |
Request body had invalid input | context contains a list of validation errors |
400 Bad Request |
CRYPTO_UNSUPPORTED_ASSET_TYPE |
The given asset type is not supported | assetType with the submitted unsupported crypto assetType |
400 Bad Request |
CRYPTO_WITHDRAWAL_ADDRESS_DUPLICATE |
A withdrawal address with the same label already exists | label with the submitted withdrawal address label |
400 Bad Request |
CRYPTO_INVALID_ETH_ADDRESS |
The given Ethereum address is invalid | address with the submitted Ethereum address |
400 Bad Request |
CRYPTO_INVALID_BTC_ADDRESS |
The given Bitcoin address is invalid | address with the submitted Bitcoin address |
404 Not Found |
CRYPTO_WALLET_NOT_FOUND |
The given wallet was not found | walletId with the submitted wallet ID |
Delete withdrawal address
Example
204 No Content
response forDELETE /wallets/:walletId/withdrawal-addresses/:withdrawalAddressId
This endpoint allows you to delete a withdrawal address for a given wallet.
HTTP Request
DELETE /wallets/:walletId/withdrawal-addresses/:withdrawalAddressId
Path Parameters
Parameter | Type | Description |
---|---|---|
walletId |
UUID | ID of wallet to submit withdrawal for |
withdrawalAddressId |
UUID | ID of withdrawal address to delete |
HTTP Response
The endpoint returns a 204 No Content
response with an empty body.
Possible errors
HTTP Status code | Error Code | Description | context |
---|---|---|---|
404 Not Found |
CRYPTO_WALLET_NOT_FOUND |
The given wallet was not found | walletId with the submitted wallet ID |
404 Not Found |
CRYPTO_WITHDRAWAL_ADDRESS_NOT_FOUND |
The given withdrawal address was not found | withdrawalAddressId with the submitted withdrawal address ID |
List crypto transactions
This endpoint returns a paged list of all transactions for a given wallet.
Example
200 OK
response forGET /wallets/:walletId/transactions
{
"data": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "OUTGOING",
"destinationAddress": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"sourceAddress": "0x1234567890abcdef",
"assetType": "ETH",
"amount": "0.1",
"amountEUR": "1000.34",
"networkFee": "0.0001",
"estimatedNetworkFee": "0.0001",
"feeAssetType": "ETH",
"status": "PENDING",
"note": "Payment for services",
"blockHeight": 123456,
"blockchainTxHash": "0x1234567890abcdef",
"created": "2021-01-01T00:00:00Z"
}
],
"metadata": {
"pagination": {
"pageSize": 1000,
"page": 0,
"totalRecords": 1
}
}
}
HTTP Request
GET /wallets/:walletId/transactions
Path Parameters
Parameter | Description |
---|---|
walletId |
ID of wallet to list crypto transactions for |
Query Parameters
Parameter | Default | Description |
---|---|---|
pageSize |
100 |
Positive integer determining how many transactions to return per page, max 1000 |
page |
0 |
Page number to retrieve, 0-indexed |
statuses |
[] |
List of CryptoTransactionStatus to query. If not provided, all types will be queried |
dateFrom |
null |
Determines the earliest transactionTime of the transactions queried. Format YYYY-MM-DD |
dateTo |
null |
Determines the latest transactionTime of the transactions queried. Format YYYY-MM-DD |
amountFrom |
null |
Determines the inclusive lower limit for the transaction amount |
amountTo |
null |
Determines the inclusive upper limit for the transaction amount |
assetTypes |
[] |
List of assetTypes code to query. If not provided, all transaction assetTypes will be queried |
text |
null |
Search term. Will query in following fields note , destinationAddress , sourceAddress |
direction |
null |
Transaction direction, INGOING or OUTGOING |
HTTP Response
200 OK
The endpoint returns a list of crypto transaction.
Possible errors
HTTP Status Code | Error Code | Description | context |
---|---|---|---|
404 Not Found |
CRYPTO_WALLET_NOT_FOUND |
The wallet with the given ID does not exist. | walletId |
400 Bad Request |
VALIDATION |
Some of the input is invalid. For example :page or :pageSize being too small |
The invalid fields and the submitted values |
Get crypto transaction
This endpoint returns a transaction for a given wallet.
Example
200 OK
response forGET /wallets/:walletId/transactions/:transactionId
{
"data": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "OUTGOING",
"destinationAddress": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"sourceAddress": "0x1234567890abcdef",
"assetType": "ETH",
"amount": "0.1",
"amountEUR": "1000.34",
"networkFee": "0.0001",
"estimatedNetworkFee": "0.0001",
"feeAssetType": "ETH",
"status": "PENDING",
"note": "Payment for services",
"blockHeight": 123456,
"blockchainTxHash": "0x1234567890abcdef",
"created": "2021-01-01T00:00:00Z"
},
"metadata": {}
}
HTTP Request
GET /wallets/:walletId/transactions/:transactionId
Path Parameters
Parameter | Description |
---|---|
walletId |
ID of wallet to get the transaction |
transactionId |
ID of transaction to be viewed |
HTTP Response
200 OK
The endpoint returns a crypto transaction.
Possible errors
HTTP Status Code | Error Code | Description | context |
---|---|---|---|
404 Not Found |
CRYPTO_WALLET_NOT_FOUND |
The wallet with the given ID does not exist. | walletId |
404 Not Found |
CRYPTOTRANSACTION_NOT_FOUND |
The transaction with the given ID does not exist. | transactionId |
Initiate crypto withdrawal
This endpoint allows you to initiate a crypto withdrawal from a given wallet.
Example request for initiating a crypto withdrawal POST /wallets/:walletId/transactions
{
"amount": 0.1,
"assetType": "ETH",
"withdrawalAddressId": "d81b63a2-efe2-4aee-abbf-a978f2037043",
"note": "Payment for services"
}
Example
201 CREATED
response forPOST /wallets/:walletId/transactions
{
"data": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "OUTGOING",
"destinationAddress": "d81b63a2-efe2-4aee-abbf-a978f2037043",
"sourceAddress": "0x1234567890abcdef",
"assetType": "ETH",
"amount": "0.1",
"amountEUR": "1000.34",
"networkFee": "0.0001",
"estimatedNetworkFee": "0.0001",
"feeAssetType": "ETH",
"status": "INITIATED",
"note": "Payment for services",
"blockHeight": null,
"blockchainTxHash": null,
"created": "2021-01-01T00:00:00Z"
},
"metadata": {}
}
HTTP Request
POST /wallets/:walletId/transactions
Path Parameters
Parameter | Type | Description |
---|---|---|
walletId |
UUID | ID of wallet to initiate crypto withdrawal for |
Request body
Field | Type | Description | Validation rules |
---|---|---|---|
amount |
Long | Amount of crypto to withdraw | required , positive |
assetType |
AssetType | Type of crypto to withdraw | required |
withdrawalAddressId |
UUID | ID of withdrawal address to withdraw to | required |
note |
String | Internal note to attach to the withdrawal | None |
HTTP Response
201 CREATED
The endpoint returns the crypto transaction that was initiated.
Possible errors
HTTP Status Code | Error Code | Description | context |
---|---|---|---|
404 Not Found |
CRYPTO_WALLET_NOT_FOUND |
The wallet with the given ID does not exist. | walletId with the submitted wallet ID |
404 Not Found |
CRYPTO_WITHDRAWAL_ADDRESS_NOT_FOUND |
The withdrawal address with the given ID does not exist. | withdrawalAddressId with the submitted withdrawal address ID |
400 Bad Request |
VALIDATION |
Some of the input is invalid. For example :amount being negative |
The invalid fields and the submitted values |
400 Bad Request |
CRYPTOTRANSACTION_INSUFFICIENT_BALANCE |
The wallet does not have enough balance to withdraw the amount | balance of the given asset, amount with the submitted amount, estimatedFee with the estimated fee from the provider, total = amount + estimatedFee which the asset balance needs to hold to initiate the crypto transaction |
400 Bad Request |
CRYPTOTRANSACTION_INCORRECT_WITHDRAWAL_ASSET_TYPE |
Transaction and withdrawal address asset types does not match | transaction.assetType with the submitted asset type, withdrawalAddress.assetType with the withdrawal address asset type |
400 Bad Request |
CRYPTOTRANSACTION_WITHDRAWAL_ADDRESS_NOT_ACTIVE |
The withdrawal address is not active | withdrawalAddress.id with the submitted withdrawal address ID, withdrawalAddress.status with the withdrawal address status |
Confirm withdrawal
This endpoint allows you to confirm a withdrawal that was initiated.
Example request for confirming a withdrawal PUT /wallets/:walletId/transactions/: transactionId/confirm
{}
Example
200 OK
response forPUT /wallets/:walletId/transactions/:transactionId/confirm
{
"data": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "OUTGOING",
"destinationAddress": "d81b63a2-efe2-4aee-abbf-a978f2037043",
"sourceAddress": "0x1234567890abcdef",
"assetType": "ETH",
"amount": "0.1",
"amountEUR": "1000.34",
"networkFee": "0.0001",
"estimatedNetworkFee": "0.0001",
"feeAssetType": "ETH",
"status": "CONFIRMED",
"note": "Payment for services",
"blockHeight": null,
"blockchainTxHash": null,
"created": "2021-01-01T00:00:00Z"
},
"metadata": {}
}
HTTP Request
PUT /wallets/:walletId/transactions/:transactionId/confirm
Path Parameters
Parameter | Type | Description |
---|---|---|
walletId |
UUID | ID of wallet to confirm crypto withdrawal for |
transactionId |
UUID | ID of crypto transaction to confirm withdrawal |
Request body
This endpoint does not accept a request body.
HTTP Response
200 OK
The endpoint returns the crypto transaction that was confirmed.
Possible errors
HTTP Status Code | Error Code | Description | context |
---|---|---|---|
404 Not Found |
CRYPTO_WALLET_NOT_FOUND |
The wallet with the given ID does not exist. | walletId with the submitted wallet ID |
404 Not Found |
CRYPTO_TRANSACTION_NOT_FOUND |
The transaction with the given ID does not exist. | transactionId with the submitted transaction ID |
400 Bad Request |
CRYPTO_TRANSACTION_ALREADY_PROCESSED |
The transaction has already been confirmed and processed. | transactionId with the submitted transaction ID |
400 Bad Request |
CRYPTOTRANSACTION_WITHDRAWAL_ADDRESS_NOT_ACTIVE |
The withdrawal address is not active | withdrawalAddress.id with the submitted withdrawal address ID, withdrawalAddress.status with the withdrawal address status |
400 Bad Request |
CRYPTOTRANSACTION_INSUFFICIENT_BALANCE |
The wallet does not have enough balance to withdraw the amount | balance of the given asset, amount with the submitted amount, estimatedFee with the estimated fee from the provider, total = amount + estimatedFee which the asset balance needs to hold to initiate the crypto transaction |
Crypto data model
This section describes the data model of each type of entity in the Crypto API:
Wallet
Example wallet object
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "My wallet",
"assets": [
{
"assetType": "ETH",
"balance": "0.1",
"depositAddress": "0x1234567890"
}
],
"withdrawalAddressTimeLockInMillis": 259200,
"withdrawalAddresses": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"label": "My Ether Wallet",
"initiated": "2023-03-20T12:39:44.177Z",
"validFrom": "2023-03-20T12:39:44.177Z",
"destinationAddress": "0x1234567890abcdef1234567890abcdef12345678",
"assetType": "ETH",
"status": "INITIATED"
}
]
}
A wallet holds a collection of assets in one or more crypto-currencies and withdrawal addresses.
Field | Type | Description |
---|---|---|
id |
UUID | The unique identifier of the wallet |
name |
String | The name of the wallet |
assets |
Assets | The list of assets in the wallet |
↳ assetType |
AssetType | assetType describes the crypto currency shortname - eg. ETH . |
↳ balance |
String | balance describes the amount of the asset in the wallet. See more on precision |
↳ depositAddress |
String | depositAddress describes the address where the asset can be deposited. |
withdrawalAddressTimeLockInMillis |
Long | The time lock in milliseconds for withdrawal addresses. The time-lock is a time period from creation of a withdrawal till it becomes active. |
withdrawalAddresses |
Withdrawal Addresses | The list of withdrawal addresses |
Crypto transaction
Example
OUTGOING
crypto transactionNote that some fields may be null depending on the transaction status. For example,
blockHeight
andblockchainTxHash
can be null for aPENDING
transaction, because the transaction may not have been broadcasted to the blockchain yet.
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "OUTGOING",
"destinationAddress": "0x1234567890abcdef",
"sourceAddress": "0x1234567890abcdef",
"assetType": "ETH",
"amount": "0.1",
"amountEUR": "1000.34",
"networkFee": "0.0001",
"estimatedNetworkFee": "0.0001",
"feeAssetType": "ETH",
"status": "PENDING",
"note": "Payment for services",
"blockHeight": 123456,
"blockchainTxHash": "0x1234567890abcdef",
"created": "2021-01-01T00:00:00Z"
}
A crypto transaction represents a transfer of crypto assets between two addresses.
Field | Type | Description |
---|---|---|
id |
UUID | The unique identifier of the crypto transaction |
walletId |
UUID | The unique identifier of the wallet the transaction belongs to |
direction |
String | direction describes the direction of the transaction. Possible values are INGOING and OUTGOING |
destinationAddress |
String | destinationAddress describes the destination address of the transaction. |
sourceAddress |
String | sourceAddress describes the source address of the transaction. |
assetType |
AssetType | assetType describes the crypto currency shortname - eg. ETH . |
amount |
String | amount describes the amount of the asset in the transaction. |
amountEUR |
String | amountEUR describes the amount of the asset in the transaction in EUR. |
networkFee |
String | networkFee describes the network fee of the transaction. |
estimatedNetworkFee |
String | estimatedNetworkFee describes the estimated network fee of the transaction. |
feeAssetType |
AssetType | feeAssetType describes the crypto currency shortname - eg. ETH - of the network fee. |
status |
CryptoTransactionStatus | status describes the status of the transaction. |
note |
String | The note field is an internal field only visible to you which can be used to describe what the transactions is for. |
blockHeight |
Long | blockHeight describes the block height of the transaction. |
blockchainTxHash |
String | blockchainTxHash describes the blockchain hash of the transaction. Can be used to look up transaction in a block explorer. |
created |
Date | The date when the transaction was created |
Crypto transactions statuses
Status | Description |
---|---|
INITIATED |
The crypto transaction has just been created. |
PENDING |
The crypto transaction is waiting to be broadcasted to the blockchain. |
CONFIRMING |
The crypto transaction is on the blockchain and is being confirmed. |
COMPLETED |
The crypto transaction has been completed. |
FAILED |
The crypto transaction has failed. |
Withdrawal address
Example withdrawal address
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"label": "My withdrawal address",
"initiated": "2021-01-01T00:00:00Z",
"validFrom": "2021-01-01T00:00:00Z",
"destinationAddress": "0x1234567890abcdef",
"assetType": "ETH",
"status": "ACTIVE"
}
A withdrawal address represents a destination address for crypto assets.
Field | Type | Description |
---|---|---|
id |
UUID | The unique identifier of the withdrawal address |
walletId |
UUID | The unique identifier of the wallet the withdrawal address belongs to |
label |
String | The unique label of the withdrawal address |
initiated |
Date | The date when the withdrawal address was created |
validFrom |
Date | The date when the withdrawal address became active |
destinationAddress |
String | The destination address of the withdrawal address |
assetType |
AssetType | assetType describes the crypto currency shortname - eg. ETH . |
status |
WithdrawalAddressStatus | status describes the status of the withdrawal address. |
Withdrawal address statuses
Notifications
Terminology for notifications
This section aims to provide a high-level overview of the different entities and concepts for notifications
The overall concept of notifications is to subscribe to get updates on specific events. The triggering events are defined below under Available Channels. This platform currently supports notifications via webhooks or email. To enable notifications, simply create a new notification via the Post Notifications endpoint. To disable notifications, simply delete any existing notifications.
Concept | Description |
---|---|
Webhook | A Webhook is a HTTP POST initiated from januar to the given endpoint carrying a payload of data. |
An Email is a simple email containing relevant info regarding the triggering event from. | |
Channel | A Channel is the entity on which to subscribe to a given available notification. See list of available channels below. |
Destination | A Destination is either an HTTP endpoint for Webhooks or an email address for Emails |
Label | A Label is simply a human readable label for any given notification |
Available Channels and destination types:
Channel | Destination type | Description |
---|---|---|
WEBHOOK_FIAT_ALL | A HTTP endpint | Subscribes to all updates on FIAT transactions, ie everytime a FIAT transaction changes state, a webhook is triggered. |
WEBHOOK_CRYPTO_ALL | A HTTP endpint | Subscribes to all updates on CRYPTO transactions, ie everytime a CRYPTO transaction changes state, a webhook is triggered. |
WITHDRAWAL_ADDRESS_UPDATE_EMAIL | A valid email address | Sends an email to the given email address when any Crypto Withdrawal Address is initiated, confirmed or cancelled. |
CRYPTOCONVERSION_STATUS_EMAIL | A valid email address | Sends an email to the given email address when any CryptoConversions are updated. |
List notifications
Example
200 OK
response forGET /notifications
{
"data": [
{
"id": "b7acbf16-7c23-4ef9-89c9-c1223dfe9a17",
"channel": "WITHDRAWAL_ADDRESS_UPDATE_EMAIL",
"destination": "test@test.com",
"label": "label"
}
],
"metadata": {}
}
This endpoint returns a list of active notifications.
HTTP Request
GET /notifications
HTTP Response
The endpoint returns a list of notification objects.
create notification
Example request for submitting a new notification at POST /notifications
{
"channel":"WITHDRAWAL_ADDRESS_UPDATE_EMAIL",
"destination":"test@test.com",
"label":"label"
}
Example
201 Created
response from submit notification
{
"data": [
{
"id": "b7acbf16-7c23-4ef9-89c9-c1223dfe9a17",
"channel": "WEBHOOK_FIAT_ALL",
"destination": "https://test.com/webhook",
"label": "label"
}
],
"metadata": {}
}
This endpoints allows you to submit a new notification.
HTTP Request
POST /notifications
Request Body
Parameter | Type | Description | Validation rules |
---|---|---|---|
channel |
String | Channel, see available list above | required |
destination |
String | email or endpoint | required |
label |
String | Human readable label | required |
HTTP Response
The endpoint returns a notification object.
Possible errors
HTTP Status code | Error Code | Description | context |
---|---|---|---|
400 Bad Request |
VALIDATION |
Request body had invalid input | |
400 Bad Request |
NOTIFICATION_INVALID |
The destination is already defined |
update notification
Example request for submitting a new notification at PUT /notifications/:notificationid
{
"channel":"WITHDRAWAL_ADDRESS_UPDATE_EMAIL",
"destination":"test@test.com",
"label":"label"
}
Example
201 Created
response from submit notification
{
"data": [
{
"id": "b7acbf16-7c23-4ef9-89c9-c1223dfe9a17",
"channel": "WITHDRAWAL_ADDRESS_UPDATE_EMAIL",
"destination": "test@test.com",
"label": "label"
}
],
"metadata": {}
}
This endpoints allows you to update an existing notification.
HTTP Request
PUT /notifications/:notificationid
Path Parameters
Parameter | Type | Description |
---|---|---|
notificationid |
UUID | ID of notification to be updated |
Request Body
Parameter | Type | Description | Validation rules |
---|---|---|---|
channel |
String | Channel, see available list above | required |
destination |
String | email or endpoint | required |
label |
String | Human readable label | required |
HTTP Response
The endpoint returns a notification object.
Possible errors
HTTP Status code | Error Code | Description | context |
---|---|---|---|
400 Bad Request |
VALIDATION |
Request body had invalid input | |
400 Bad Request |
NOTIFICATION_NOT_FOUND |
The notification can not be found |
Delete notification
This endpoint allows you to delete a given notification.
HTTP Request
DELETE /notifications/:notificationid
Path Parameters
Parameter | Type | Description |
---|---|---|
notificationid |
UUID | ID of notification to be deleted |
HTTP Response
The endpoint returns a 204 No Content
response with an empty body.
Possible errors
HTTP Status code | Error Code | Description | context |
---|---|---|---|
404 Not Found |
NOTIFICATION_NOT_FOUND |
The given notification was not found |
Notification Data Model
Example Notification object
{
"id": "b7acbf16-7c23-4ef9-89c9-c1223dfe9a17",
"channel": "WITHDRAWAL_ADDRESS_UPDATE_EMAIL",
"destination": "test@test.com",
"label": "Withdrawal address email recipient"
}
Field | Type | Description |
---|---|---|
id |
UUID | The unique identifier of the notification |
channel |
String | The channel of the wallet |
destination |
String | Either email or HTTP endpoint |
label |
String | Human readable label. |