This document outlines the required steps to integrate with Zodia using our API.
Document created on April 20th, 2021. Last updated on February 4th, 2023.
Contact: customerservice@zodia.io
pip install cryptography
pip install requests
Before invoking Zodia's API, your company's account must be set up onto Zodia by Zodia's staff.
To complete this setup, your company must generate a key pair. We will refer to these keys as:
Those keys must be RSA keys (encoded in base 64) with a minimum size of 2048 bits.
Once generated, your company must share the public key company_pub_key with Zodia's staff: customerservice@zodia.io
WARNING: You must never share the private key company_pri_key with anyone including Zodia staff. This private key must be stored securely
Below is an example of how to generate a key pair for the company named ZTEST:
import os
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
def generate_rsa_keypair(company):
rsa_private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend())
private_key_pem = rsa_private_key.private_bytes(serialization.Encoding.PEM,
serialization.PrivateFormat.PKCS8,
serialization.NoEncryption())
with open(os.path.join("keys", company + ".private.pem"), "wb") as private_key_out:
private_key_out.write(private_key_pem)
rsa_public_key = rsa_private_key.public_key()
public_key_pem = rsa_public_key.public_bytes(serialization.Encoding.PEM,
serialization.PublicFormat.SubjectPublicKeyInfo)
with open(os.path.join("keys", company + ".public.pem"), "wb") as public_key_out:
public_key_out.write(public_key_pem)
if __name__ == '__main__':
generate_rsa_keypair("ZTEST")
# Private key "company_pri_key" can be found in the file "ZTEST.private.pem"
# Public key "company_pub_key" can be found in the file "ZTEST.public.pem"
At least two API users must be added to your company's account.
Important note
If the company has already been set up as explained above in the document, then Zodia customer service cannot create any API accounts on the created company. Only your company user maker will be able to create these two required API accounts.
However, if the company has not already been set up on Zodia UI, then Zodia onboarding team can create the company with the two required API accounts. Other user accounts can also be created by Zodia team at the time of the new company creation.
By convention, the API users should have an id starting with api-. Examples: api-maker and api-checker
To onboard these users, you must generate a key pair for each API user. We will refer to these keys as:
Each API user is composed of three pieces of information:
These 3 pieces of information must then be shared with Zodia's staff: customerservice@zodia.io
Applying the two "How-to" steps below results in the following example:
WARNING: You must never share the private key api_user_pri_key with anyone including Zodia staff. This private key must be stored securely
Please note that the Elliptic Curve that must be used to generate those keys is SECP256R1
Below is an example of how to generate a key pair for the user whose email is api-maker@zodia.io:
import os
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
def generate_ec_keypair(user):
ec_private_key = ec.generate_private_key(ec.SECP256R1(), default_backend())
private_key_pem = ec_private_key.private_bytes(serialization.Encoding.PEM,
serialization.PrivateFormat.PKCS8,
serialization.NoEncryption())
with open(os.path.join("keys", user + ".private.pem"), "wb") as private_key_out:
private_key_out.write(private_key_pem)
ec_public_key = ec_private_key.public_key()
public_key_pem = ec_public_key.public_bytes(serialization.Encoding.PEM,
serialization.PublicFormat.SubjectPublicKeyInfo)
with open(os.path.join("keys", user + ".public.pem"), "wb") as public_key_out:
public_key_out.write(public_key_pem)
if __name__ == "__main__":
generate_ec_keypair("[email protected]")
# Private key "api_user_pri_key" can be found in the file "[email protected]"
# Private key "api_user_pub_key" can be found in the file "[email protected]"
Once you have the public key of the API user, you can generate the api user id by doing:
import os, binascii
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
def generate_zodia_user_id(user):
with open(os.path.join("keys", user + ".public.pem"), "rb") as public_key_in:
ec_public_key = serialization.load_pem_public_key(public_key_in.read(), backend=default_backend())
public_key_bytes = ec_public_key.public_bytes(serialization.Encoding.DER,
serialization.PublicFormat.SubjectPublicKeyInfo)
digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
digest.update(public_key_bytes)
sha256 = digest.finalize()
hex_id = binascii.hexlify(sha256).decode('UTF-8')
return user + "::" + hex_id[-10:]
if __name__ == "__main__":
zodia_user_id = generate_zodia_user_id("[email protected]")
print(zodia_user_id) # [email protected]::76b728bb89
In order to provide a high-quality service, Zodia's API is rate limited. The default limits are:
Please reach out to Zodia if you wish to adjust the rate limit for given endpoints.
If the rate limit is exceeded, the API will respond with the status code HTTP 429 Too Many Requests
. Please refer to the section Error codes.
Zodia's API authentication requires each request to be signed.
These requests must be signed using company_pri_key, the private key of your company.
All REST requests must contain the following headers:
All request bodies should have content type application/json
and be valid JSON.
Before submitting a payload contained in a POST
request, you will need to sign with api_user_pri_key, your private key as an API user.
The content that must be signed is the stringified value of a part of this payload.
For more details about a stringified value, see json-stable-stringify
The signed payload must not include optional and empty fields
The content that must be signed is the stringified value of the object named request.
Example: assuming you want to submit the command to create new outgoing transaction with bitcoins, you will have to submit the payload:
{
"request": {
"author": {
"id": "2336cf5b-a9d2-45e8-b384-5b45d0eb4f03",
"domainId": "cef1a96b-aa13-443a-b4cc-e3286f2af910"
},
"expiryAt": "2022-01-05T10:54:48Z",
"targetDomainId": "cef1a96b-aa13-443a-b4cc-e3286f2af910",
"id": "4ffea8f1-aa6d-40b3-9581-070eca1d3529",
"payload": {
"accountId": "ea34669c-226d-430c-8633-a3809414536c",
"parameters": {
"outputs": [
{
"destination": {
"type": "Address",
"address": "2N3oum61eFbwBvA8roU7YuR8UXnmMxr1tCE"
},
"amount": "5000"
}
],
"feeStrategy": {
"priority": "High",
"type": "Priority"
},
"maximumFee": "10000",
"type": "Bitcoin"
},
"id": "91e8cfd2-8ba8-483f-8034-fde52fb82fe7",
"description": "Create an intent for tx out",
"customProperties": {},
"type": "v0_CreateTransactionOrder"
},
"description": "Create an intent for tx out",
"customProperties": {},
"type": "Propose"
},
"signature": "{{signature}}"
}
where {{signature}} is the value obtained by signing the stringified value of the object request. Below is an example of how to sign:
import os, base64, json
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec
def stringify_transaction_details():
transaction_details = {
"author": {
"id": "2336cf5b-a9d2-45e8-b384-5b45d0eb4f03",
"domainId": "cef1a96b-aa13-443a-b4cc-e3286f2af910"
},
"expiryAt": "2022-01-05T10:54:48Z",
"targetDomainId": "cef1a96b-aa13-443a-b4cc-e3286f2af910",
"id": "4ffea8f1-aa6d-40b3-9581-070eca1d3529",
"payload": {
"accountId": "ea34669c-226d-430c-8633-a3809414536c",
"parameters": {
"outputs": [
{
"destination": {
"type": "Address",
"address": "2N3oum61eFbwBvA8roU7YuR8UXnmMxr1tCE"
},
"amount": "5000"
}
],
"feeStrategy": {
"priority": "High",
"type": "Priority"
},
"maximumFee": "10000",
"type": "Bitcoin"
},
"id": "91e8cfd2-8ba8-483f-8034-fde52fb82fe7",
"description": "Create an intent for tx out",
"customProperties": {},
"type": "v0_CreateTransactionOrder"
},
"description": "Create an intent for tx out",
"customProperties": {},
"type": "Propose"
}
return json.dumps(transaction_details, sort_keys=True, separators=(',', ':'))
def sign_transaction_details(details, user):
with open(os.path.join("keys", user + ".private.pem"), "rb") as private_key_in:
ec_private_key = serialization.load_pem_private_key(private_key_in.read(),
password=None,
backend=default_backend())
signed_payload = ec_private_key.sign(str.encode(details), ec.ECDSA(hashes.SHA256()))
b64_signed_payload = base64.b64encode(signed_payload).decode('UTF-8')
return b64_signed_payload
def create_transaction_payload(details, signature):
payload = {
"request": json.loads(details),
"signature": signature
}
}
return json.dumps(payload, sort_keys=True, separators=(',', ':'))
if __name__ == "__main__":
stringified_details = stringify_transaction_details()
user_signature = sign_transaction_details(stringified_details, "[email protected]")
transaction_payload = create_transaction_payload(stringified_details, user_signature)
print(transaction_payload) # {"request":{"author":{"id":"2336cf5b-a9d2-45e8-b384-5b45d0eb4f03","domainId":"cef1a96b-aa13-443a-b4cc-e3286f2af910"},"expiryAt":"2022-01-05T10:54:48Z","targetDomainId":"cef1a96b-aa13-443a-b4cc-e3286f2af910","id":"4ffea8f1-aa6d-40b3-9581-070eca1d3529","payload":{"accountId":"ea34669c-226d-430c-8633-a3809414536c","parameters":{"outputs":[{"destination":{"type":"Address","address":"2N3oum61eFbwBvA8roU7YuR8UXnmMxr1tCE"},"amount":"5000"}],"feeStrategy":{"priority":"High","type":"Priority"},"maximumFee":"10000","type":"Bitcoin"},"id":"91e8cfd2-8ba8-483f-8034-fde52fb82fe7","description":"Create an intent for tx out","customProperties":{},"type":"v0_CreateTransactionOrder"},"description":"Create an intent for tx out","customProperties":{},"type":"Propose"},"signature":"MEQCIHuLPOFmbnjWnJ0l6QpYRLMh/6LTwIV6LNlGXRiChProAiBjDQCsvbsGxb6pw9Il/m8zIFmZ+Wh3QFwBmIZJCOk8kA=="}
You will obtain the payload below (prettified for the documentation) that you can submit to Zodia, once you have signed the whole request:
{
"request": {
"author": {
"id": "2336cf5b-a9d2-45e8-b384-5b45d0eb4f03",
"domainId": "cef1a96b-aa13-443a-b4cc-e3286f2af910"
},
"expiryAt": "2022-01-05T10:54:48Z",
"targetDomainId": "cef1a96b-aa13-443a-b4cc-e3286f2af910",
"id": "4ffea8f1-aa6d-40b3-9581-070eca1d3529",
"payload": {
"accountId": "ea34669c-226d-430c-8633-a3809414536c",
"parameters": {
"outputs": [
{
"destination": {
"type": "Address",
"address": "2N3oum61eFbwBvA8roU7YuR8UXnmMxr1tCE"
},
"amount": "5000"
}
],
"feeStrategy": {
"priority": "High",
"type": "Priority"
},
"maximumFee": "10000",
"type": "Bitcoin"
},
"id": "91e8cfd2-8ba8-483f-8034-fde52fb82fe7",
"description": "Create an intent for tx out",
"customProperties": {},
"type": "v0_CreateTransactionOrder"
},
"description": "Create an intent for tx out",
"customProperties": {},
"type": "Propose"
},
"signature": "MEQCIHuLPOFmbnjWnJ0l6QpYRLMh/6LTwIV6LNlGXRiChProAiBjDQCsvbsGxb6pw9Il/m8zIFmZ+Wh3QFwBmIZJCOk8kA=="
}
Once the payload (for POST
requests) is signed, you will need to sign the request that you send to Zodia.
Using : as separator, please concatenate the values of:
POST
requests)As an example for a GET
request, the resulting string will be:ZTEST:c730a02f-105d-4899-87aa-b1b8280e4a7e:1620141458133:https://dummy.server/api/core/wallets/ZTEST-NOBENF-8P8XKKAO/transactions/out?limit=25&from=2021-03-29:
The content of the header signature
is generated by signing the string above with company_pri_key.
Example of code showing how to sign the request:
import os, base64, time, uuid, requests
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
def sign(data_to_sign, private_key):
data_bytes = str.encode(data_to_sign)
signature = private_key.sign(data_bytes, padding.PKCS1v15(), hashes.SHA256())
return base64.b64encode(signature).decode('UTF-8')
def sign_for_zodia(company_identifier, url, payload):
request_identifier = str(uuid.uuid4())
request_timestamp = str(int(time.time() * 1000))
data_to_sign = ":".join([company_identifier, request_identifier, request_timestamp, url, payload])
print(data_to_sign) # ZTEST:c730a02f-105d-4899-87aa-b1b8280e4a7e:1620141458133:https://dummy.server/api/core/wallets/ZTEST-NOBENF-8P8XKKAO/transactions/out?limit=25&from=2021-03-29:
with open(os.path.join("keys", company_identifier + ".private.pem"), "rb") as private_key_in:
rsa_private_key = serialization.load_pem_private_key(private_key_in.read(),
password=None,
backend=default_backend())
signature = sign(data_to_sign, rsa_private_key)
return company_identifier, request_identifier, request_timestamp, signature
if __name__ == "__main__":
full_url = "https://dummy.server/api/core/wallets/ZTEST-NOBENF-8P8XKKAO/transactions/out?limit=25&from=2021-03-29"
headers = sign_for_zodia("ZTEST", full_url, "")
response = requests.get(full_url, headers={
"company-identifier": headers[0], # ZTEST
"request-identifier": headers[1], # c730a02f-105d-4899-87aa-b1b8280e4a7e
"request-timestamp": headers[2], # 1620141458133
"signature": headers[3] # aZBZNDeDJomgRBZFhV24MbdlyfSiqJuCMgz5mSl+dpxtDDgbadTuin0z920eBD2YFP5g3ccakguQUXPMuLp4Umyet3hGYXb2GiMkKSIA8XocdF8uG2xReSZq+JSbuDSO7yQcxXVK10A6mL2f/zJuTFBRl20jegiHOBcbDlAOUkWS3Vam3KRLA/Nd8ZwOhK6XZbtZWGz0AW9obE7cpEwqUEposucx7J462XAaM9Duh+CF1ALhuo67G0hLYAtwqryRVhUdBvVrqoWgGu3quxfIYgG/8okYv2hHjzBtIfo2VREi4TlgsRXvGPQpSI534S8o9laa5Ddq1f6N2u1sXkE97g==
})
With V2 endpoints there is a change to the flow for creating and approving a wallet and outgoing transaction.
You will need to retrieve the payload from Zodia after initiating creation to sign and submit it.
Creating/approving wallets and outgoing transfers in V2 use the following flows:
Creating an Outgoing Transaction
Approving an Outgoing Transaction
Zodia's API offers a number of error codes to facilitate your usage and troubleshooting.
Zodia uses HTTP response codes to indicate the success or failure of an API request. In general:
200
indicate success4xx
range indicate a failure given the information provided(e.g. a required parameter was omitted, etc...)500
indicate an error with Zodia's serversIn addition to these HTTP response codes, Zodia provides in the response payload:
ER-
that should be shared with Zodia for troubleshootingThe table below describes some errors you may encounter:
HTTP status code | Error code | Error message | Description |
---|---|---|---|
400 | ER-101 | Missing mandatory field: field_name | A mandatory field is missing in the payload received by Zodia |
400 | ER-102 | Entity with id: entity_id does not exist | You are trying to use an entity (company, wallet, transaction, etc…) that does not exist |
400 | ER-103 | Size of the field: field_name must be between min_value and max_value | Length of the value provided does not match the expected size |
400 | ER-104 | Entity with id: entity_id already exists | You are trying to create an entity (company, wallet, transaction, etc…) which already exists |
400 | ER-107 | Field: field_name must not be blank |
|
400 | ER-108 | Field: field_name does not match the expected pattern: regexp_value | You sent a value that does not match the pattern expected by Zodia |
400 | ER-111 | Value of the field: field_name is not a supported cryptocurrency | The cryptocurrency provided is not currently supported by Zodia |
400 | ER-112 | Field: field_name must not be empty | You sent an empty value/list while Zodia is expecting at least one value |
400 | ER-113 | Entity with id: entity_id is deactivated | You are trying to use a deactivated entity |
400 | ER-114 | Field: field_name does not match with user's company | The value you provided for the field (usually "domainId") does not match your company's identifier |
400 | ER-115 | Field: field_name does not match with resource parameter: path_parameter | The value you provided in the payload does not match the path parameter used in the resource |
400 | ER-116 | Value of the field: field_name must contain only digits | You sent a value that is not a numeric value |
400 | ER-117 | Value of the field: field_name must be equal to value | You must send a value strictly equal to the value expected by Zodia |
400 | ER-121 | Field: field_name must be greater than or equal to value | You must send a value greater than or equal to the value expected by Zodia |
400 | ER-122 | Field: field_name must be less than or equal to value | You must send a value lesser than or equal to the value expected by Zodia |
400 | ER-124 | Only max_value minutes of drift are allowed | Zodia allows 5 minute of drift between the signed timestamp provided and the instant that Zodia receives the query |
400 | ER-202 | Header: header must not be blank |
|
405 | ER-204 | Available methods : available_methods | You must choose from the available methods for an endpoint. Example: GET,POST |
429 | ER-208 | Rate limit exceeded. Try again later | You exceeded the number of queries per second defined by Zodia Please refer to the section Rate limiting |
429 | ER-209 | Daily quota exhausted. Try again later | You exhausted the number of queries per day defined by Zodia Please refer to the section Rate limiting |
401 | ER-210 | Signature verification failed | Zodia was not able to verify the signature you provided. Either because:
Please refer to the section Authentication |
401 | ER-211 | Access to this resource is denied | The entitlements defined by Zodia don’t allow you to access this resource |
400 | ER-253 | Not enough funds | The transfer instruction cannot be created as there are not sufficient funds to pay for the amount and/or fee |
400 | ER-501 | Transaction creation is rejected | The transfer instruction has been rejected due to sender or recipient details |
400 | ER-502 | Mismatch between transaction's wallet currency and field: field_name | The cryptocurrency you provided for the field is not consistent with the wallet used for the transaction |
400 | ER-503 | Value of the field: field_name is not adapted to this endpoint | You provided a value that is not supported by the endpoint you used. Example: "preburn" while using the endpoint "/api/core/transactions" |
400 | ER-504 | Mismatch between field: field1_name and field: field2_name | The fields "field1" and "field2" must have the same value |
400 | ER-505 | Mismatch between transaction's wallet and field: field_name | The value you provided for the field does not match the wallet used for the transaction |
400 | ER-506 | Mismatch between transaction's company and field: field_name | The value you provided does not match the company used for the transaction |
400 | ER-512 | Eth transaction fee-included not allowed | You can't submit a transaction ETH included fees |
400 | ER-601 | Ledger wallet is not compatible with this operation | You are trying to initiate a contract-related transaction while using a wallet that does not support this operation |
400 | ER-604 | Error retrieving the wallet address | Zodia was not able to retrieve the address associated to this wallet |
500 | ER-1 | Unexpected error: error | Zodia encountered an unexpected error and can not fulfill the request Please contact Zodia with the error's identifier beginning with the keyword "ERR" |
The units used in the API are the smallest denomination for a currency per the reference table below:
Currency | Unit |
---|---|
BTC | Satoshi |
ETH | WEI |
BCH | Satoshi |
LTC | Litoshi |
The API will return status codes for some calls relating to wallets and transactions. These status codes can be mapped to human-readable messages using the following reference tables:
API Status - V2 | Definition |
---|---|
ACTIVE | Wallet currently active - Funds available |
INACTIVE | Wallet not active - Funds are not available |
CONFIRMED | New client request submitted and validated |
CANCELLED_BY_MAKER | Rejected by client, wallet not created |
CONFIRMATION_TIMEOUT | New client request submitted but not approved within the expiry time |
APPROVAL_TIMEOUT | Client approval not completed within the expiry time |
PENDING_AUTH | Client and Zodia approvals pending |
PROCESSING | Client approval is pending / Client approval is completed but Zodia approval is pending |
AUTHORISED | Client and Zodia approvals completed |
ACTIVE | Client request completed, wallet created |
REJECTED_BY_AUTHORIZER / REJECTED_BY_SYTEM | Rejected by client / Rejected by Zodia |
FAILED | Wallet creation failed, not completed |
FAILED | Wallet creation failed, not completed |
TIMEOUT | Approvals not completed within the expiry time |
DRAFT | Wallet can still be edited before submitted |
DELETED | Wallet deleted before submitted |
API Status - V2 | Definition |
---|---|
CONFIRMED | New client request submitted and validated |
CANCELLED_BY_MAKER | Rejected by client, outgoing transaction not created |
CONFIRMATION_TIMEOUT | New client request submitted but not approved within the expiry time |
APPROVAL_TIMEOUT | Client approval not completed within the expiry time |
PENDING_AUTH | Client and Zodia approvals pending |
PROCESSING | Client approval is pending / Client approval is completed but Zodia approval is pending |
AUTHORISED | Client and Zodia approvals completed |
ACTIVE | Client request completed, outgoing transaction created |
REJECTED_BY_AUTHORIZER / REJECTED_BY_SYTEM | Rejected by client / Rejected by Zodia |
FAILED | Outgoing transaction failed, not completed |
FAILED | Outgoing transaction failed, not completed |
CONFIRMATION_COMPLETED | Outgoing transaction confirmed after x blocks |
APPROVAL_TIMEOUT | Approvals not completed within the expiry time |
FAILED | Outgoing transaction failed, not completed |
FAILED | Outgoing transaction failed, not completed |
READY_FOR_RELEASE | Outgoing transaction waiting to be processed |
POSTED_ON_CHAIN | Outgoing transaction broadcasted on-chain |
UNDER_INVESTIGATION | Outgoing transaction under investigation by Zodia |
API Status - V2 | Definition |
---|---|
PENDING_UNLOCK | Incoming transaction detected on-chain |
PENDING_AUTH | Zodia approvals pending |
PROCESSING | Zodia approvals pending |
UNLOCK_IN_PROGRESS | Zodia approvals completed |
UNLOCKED | Incoming transaction is unlocked - Funds available |
CONFIRMATION_COMPLETED | Incoming transaction confirmed after x blocks |
REJECTED_BY_SYTEM | Rejected by Zodia |
APPROVAL_TIMEOUT | Approvals not completed within the expiry time |
UNDER_INVESTIGATION | Incoming transaction under investigation by Zodia |
{- "wallets": [
- {
- "walletId": "ZTEST-NOBENF-849P8XKKAO",
- "walletName": "Demo wallet",
- "walletCompany": "ZTEST",
- "status": "ACTIVE",
- "valid": true,
- "registeredComplianceKey": true,
- "blockchain": "string",
- "assetBalances": [
- {
- "currency": "string",
- "unitCurrency": "string",
- "availableUnitBalance": "641400",
- "ledgerUnitBalance": "641400",
- "pendingOutUnitBalance": "0",
- "pendingInUnitBalance": "0",
- "availableBalance": "0.006414",
- "ledgerBalance": "0.006414",
- "pendingOutBalance": "0",
- "pendingInBalance": "0"
}
], - "createdAt": "2021-08-03T18:17:57Z",
- "updatedAt": "2021-08-03T18:17:57Z"
}
]
}
name required | string [ 1 .. 128 ] characters ^[a-zA-Z0-9 -]+$ Display name of the wallet |
currency required | string Currency of the wallet |
beneficiaryId | string [ 14 .. 32 ] characters ID of the beneficiary of the wallet |
submitterEmail required | string Mail of the user creating the wallet |
walletId required | string [ 1 .. 40 ] characters <companyId>-[NOBENF|<beneficiaryId>]-API-* ID of the wallet |
{- "name": "Demo wallet",
- "currency": "string",
- "beneficiaryId": "BNF-ZTEST-0DFUSJPF7A",
- "walletId": "ZTEST-NOBENF-849P8XKKAO"
}
{- "id": "ABCD"
}
{- "walletId": "ZTEST-NOBENF-849P8XKKAO",
- "walletName": "Demo wallet",
- "walletCompany": "ZTEST",
- "status": "ACTIVE",
- "valid": true,
- "registeredComplianceKey": true,
- "blockchain": "string",
- "assetBalances": [
- {
- "currency": "string",
- "unitCurrency": "string",
- "availableUnitBalance": "641400",
- "ledgerUnitBalance": "641400",
- "pendingOutUnitBalance": "0",
- "pendingInUnitBalance": "0",
- "availableBalance": "0.006414",
- "ledgerBalance": "0.006414",
- "pendingOutBalance": "0",
- "pendingInBalance": "0"
}
], - "createdAt": "2021-08-03T18:17:57Z",
- "updatedAt": "2021-08-03T18:17:57Z"
}
{- "request": {
- "author": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "domainId": "8a0b02c3-fdd8-452e-bc6e-ef07a335ec7e"
}, - "expiryAt": "2022-01-09T10:51:00Z",
- "targetDomainId": "cef1a96b-aa13-443a-b4cc-e3286f2af910",
- "id": "b0393b72-83e8-4809-ba89-7e63ea11a49a",
- "payload": {
- "id": "39ed5bd5-5844-44b9-b4b4-6d3533c3b3e9",
- "alias": "ZTEST-NOBENF-849P8XKKAO",
- "providerDetails": {
- "vaultId": "2d95a0f0-2acf-11ec-8d3d-0242ac130003",
- "keyStrategy": "VaultHard",
- "type": "Vault"
}, - "ledgerId": "bitcoin-testnet",
- "lock": "Unlocked",
- "description": "Description of my account",
- "customProperties": {
- "property1": "string",
- "property2": "string"
}, - "type": "v0_CreateAccount"
}, - "description": "create an intent for account",
- "customProperties": {
- "property1": "string",
- "property2": "string"
}, - "type": "Propose"
}, - "signature": "MEUCIC3VIuw4pfk+BLnZrk1qklGS9phAlQFSQoAnlhw59x7cAiEAm5nq8ANlHcRNcONj5FXXl1v0EK5U8gZyQ22geFSsFL8="
}
walletId required | string |
required | object Details of the wallet being created |
signature required | string Signature of the "request" field above |
{- "request": {
- "author": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "domainId": "8a0b02c3-fdd8-452e-bc6e-ef07a335ec7e"
}, - "expiryAt": "2022-01-09T10:51:00Z",
- "targetDomainId": "cef1a96b-aa13-443a-b4cc-e3286f2af910",
- "id": "b0393b72-83e8-4809-ba89-7e63ea11a49a",
- "payload": {
- "id": "39ed5bd5-5844-44b9-b4b4-6d3533c3b3e9",
- "alias": "ZTEST-NOBENF-849P8XKKAO",
- "providerDetails": {
- "vaultId": "2d95a0f0-2acf-11ec-8d3d-0242ac130003",
- "keyStrategy": "VaultHard",
- "type": "Vault"
}, - "ledgerId": "bitcoin-testnet",
- "lock": "Unlocked",
- "description": "Description of my account",
- "customProperties": {
- "property1": "string",
- "property2": "string"
}, - "type": "v0_CreateAccount"
}, - "description": "create an intent for account",
- "customProperties": {
- "property1": "string",
- "property2": "string"
}, - "type": "Propose"
}, - "signature": "MEUCIC3VIuw4pfk+BLnZrk1qklGS9phAlQFSQoAnlhw59x7cAiEAm5nq8ANlHcRNcONj5FXXl1v0EK5U8gZyQ22geFSsFL8="
}
{- "id": "ABCD"
}
walletId required | string |
approverId required | string |
{- "request": {
- "author": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "domainId": "8a0b02c3-fdd8-452e-bc6e-ef07a335ec7e"
}, - "expiryAt": "2021-03-29T11:34:53Z",
- "targetDomainId": "6319e504-a82c-4cca-93a5-b46145310588",
- "intentId": "d7492216-bec4-4daf-8326-5a05aaafe561",
- "proposalSignature": "string",
- "type": "Approve"
}, - "signature": "MEUCIC3VIuw4pfk+BLnZrk1qklGS9phAlQFSQoAnlhw59x7cAiEAm5nq8ANlHcRNcONj5FXXl1v0EK5U8gZyQ22geFSsFL8="
}
walletId required | string |
required | object Details of the request being approved/rejected |
signature required | string Signature of the "request" field above |
{- "request": {
- "author": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "domainId": "8a0b02c3-fdd8-452e-bc6e-ef07a335ec7e"
}, - "expiryAt": "2021-03-29T11:34:53Z",
- "targetDomainId": "6319e504-a82c-4cca-93a5-b46145310588",
- "intentId": "d7492216-bec4-4daf-8326-5a05aaafe561",
- "proposalSignature": "string",
- "type": "Approve"
}, - "signature": "MEUCIC3VIuw4pfk+BLnZrk1qklGS9phAlQFSQoAnlhw59x7cAiEAm5nq8ANlHcRNcONj5FXXl1v0EK5U8gZyQ22geFSsFL8="
}
{- "id": "ABCD"
}
walletId required | string |
limit | integer [ 1 .. 1024 ] Default: 10 Number of results per request |
from | string Examples:
Start and inclusive date/time of the query |
to | string Examples:
End and inclusive date/time of the query |
{- "transfers": [
- {
- "companyId": "ZTEST",
- "fromAddress": [
- "tb1qtx38mjl8gyg9gjk58tw88upytxwyxhmcqsv3le"
], - "toWallet": "ZTEST-NOBENF-849P8XKKAO",
- "toAddress": "2Mz5ZH9e6Q53QfK2E1Azaos3Vq62niibhc1",
- "transferId": "TRI-ZTEST-63Q4DZ0KJP",
- "transferStatus": "PENDING_UNLOCK",
- "amountLedger": 641400,
- "ledgerRef": "2f6e77f8c4313d0925f71acf19a659398115bdf903e3af06b3b1776e756c096f",
- "actionId": "TX_IN_ACTION-ZTEST-7LE2JCPZ3D",
- "method": "TRANSFER",
- "createdAt": "2021-08-03T18:17:57Z",
- "currency": "string"
}
]
}
walletId required | string |
limit | integer [ 1 .. 1024 ] Default: 10 Number of results per request |
from | string Examples:
Start and inclusive date/time of the query |
to | string Examples:
End and inclusive date/time of the query |
{- "transfers": [
- {
- "companyId": "ZTEST",
- "fromWallet": "ZTEST-NOBENF-849P8XKKAO",
- "toAddress": "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt",
- "consumerMetadata": "metadata",
- "transferId": "TRO-API-ZTEST-4001",
- "transferStatus": "CONFIRMED",
- "amountLedger": 641400,
- "feeType": "HIGH",
- "feeAmountLedger": 165,
- "ledgerRef": "fd1c22fd097501606fddbc7d22e5009d45e9e6cb7115ad109a46f8319a385bd4",
- "createdAt": "2021-08-03T18:17:57Z",
- "currency": "string",
- "feeCurrency": "string"
}
]
}
walletId required | string [ 1 .. 40 ] characters id of the wallet you want to use |
transactionId required | string [ 1 .. 40 ] characters id of transaction which will be created |
amount required | string amount to send in Unit |
currency | string Default: "the wallet currency" currency of the transfer |
subtractFee required | boolean subtract fee |
recipientId required | string to address |
description | string a quick description of the transaction |
submitterId required | string email of submitter |
{- "walletId": "ZTEST-NOBENF-849P8XKKAO",
- "transactionId": "TRI-ZTEST-63Q4DZ0KJP",
- "amount": "100",
- "currency": "eth",
- "subtractFee": true,
- "recipientId": "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt",
- "description": "First transaction",
- "submitterId": "[email protected]"
}
{- "id": "ABCD"
}
transactionId required | string |
{- "request": {
- "author": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "domainId": "8a0b02c3-fdd8-452e-bc6e-ef07a335ec7e"
}, - "expiryAt": "2022-01-09T10:51:00Z",
- "targetDomainId": "cef1a96b-aa13-443a-b4cc-e3286f2af910",
- "id": "b0393b72-83e8-4809-ba89-7e63ea11a49a",
- "payload": {
- "id": "0d0ab26c-bb74-42af-841a-78c94c5f9453",
- "accountId": "692b87f6-2c34-4a2c-8af7-040b74c7bbd0",
- "parameters": {
- "outputs": [
- {
- "destination": {
- "address": "2N3oum61eFbwBvA8roU7YuR8UXnmMxr1tCE",
- "type": "Address"
}, - "amount": "1000",
- "paysFee": false
}
], - "feeStrategy": {
- "priority": "High",
- "type": "Priority"
}, - "maximumFee": "10000",
- "type": "Bitcoin"
}, - "description": "Create an intent for tx out",
- "customProperties": {
- "property1": "string",
- "property2": "string"
}, - "type": "v0_CreateTransactionOrder"
}, - "description": "Create an intent for tx out",
- "customProperties": {
- "property1": "string",
- "property2": "string"
}, - "type": "Propose"
}, - "signature": "MEUCIC3VIuw4pfk+BLnZrk1qklGS9phAlQFSQoAnlhw59x7cAiEAm5nq8ANlHcRNcONj5FXXl1v0EK5U8gZyQ22geFSsFL8="
}
required | object Details of the transaction being created |
signature required | string Signature of the "request" field above |
{- "request": {
- "author": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "domainId": "8a0b02c3-fdd8-452e-bc6e-ef07a335ec7e"
}, - "expiryAt": "2022-01-09T10:51:00Z",
- "targetDomainId": "cef1a96b-aa13-443a-b4cc-e3286f2af910",
- "id": "b0393b72-83e8-4809-ba89-7e63ea11a49a",
- "payload": {
- "id": "0d0ab26c-bb74-42af-841a-78c94c5f9453",
- "accountId": "692b87f6-2c34-4a2c-8af7-040b74c7bbd0",
- "parameters": {
- "outputs": [
- {
- "destination": {
- "address": "2N3oum61eFbwBvA8roU7YuR8UXnmMxr1tCE",
- "type": "Address"
}, - "amount": "1000",
- "paysFee": false
}
], - "feeStrategy": {
- "priority": "High",
- "type": "Priority"
}, - "maximumFee": "10000",
- "type": "Bitcoin"
}, - "description": "Create an intent for tx out",
- "customProperties": {
- "property1": "string",
- "property2": "string"
}, - "type": "v0_CreateTransactionOrder"
}, - "description": "Create an intent for tx out",
- "customProperties": {
- "property1": "string",
- "property2": "string"
}, - "type": "Propose"
}, - "signature": "MEUCIC3VIuw4pfk+BLnZrk1qklGS9phAlQFSQoAnlhw59x7cAiEAm5nq8ANlHcRNcONj5FXXl1v0EK5U8gZyQ22geFSsFL8="
}
{- "id": "ABCD"
}
transactionId required | string |
approverId required | string |
{- "request": {
- "author": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "domainId": "8a0b02c3-fdd8-452e-bc6e-ef07a335ec7e"
}, - "expiryAt": "2021-03-29T11:34:53Z",
- "targetDomainId": "6319e504-a82c-4cca-93a5-b46145310588",
- "intentId": "d7492216-bec4-4daf-8326-5a05aaafe561",
- "proposalSignature": "string",
- "type": "Approve"
}, - "signature": "MEUCIC3VIuw4pfk+BLnZrk1qklGS9phAlQFSQoAnlhw59x7cAiEAm5nq8ANlHcRNcONj5FXXl1v0EK5U8gZyQ22geFSsFL8="
}
required | object Details of the request being approved/rejected |
signature required | string Signature of the "request" field above |
{- "request": {
- "author": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "domainId": "8a0b02c3-fdd8-452e-bc6e-ef07a335ec7e"
}, - "expiryAt": "2021-03-29T11:34:53Z",
- "targetDomainId": "6319e504-a82c-4cca-93a5-b46145310588",
- "intentId": "d7492216-bec4-4daf-8326-5a05aaafe561",
- "proposalSignature": "string",
- "type": "Approve"
}, - "signature": "MEUCIC3VIuw4pfk+BLnZrk1qklGS9phAlQFSQoAnlhw59x7cAiEAm5nq8ANlHcRNcONj5FXXl1v0EK5U8gZyQ22geFSsFL8="
}
{- "id": "ABCD"
}
{- "companyId": "ZTEST",
- "fromWallet": "ZTEST-NOBENF-849P8XKKAO",
- "toAddress": "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt",
- "consumerMetadata": "metadata",
- "transferId": "TRO-API-ZTEST-4001",
- "transferStatus": "CONFIRMED",
- "amountLedger": 641400,
- "feeType": "HIGH",
- "feeAmountLedger": 165,
- "ledgerRef": "fd1c22fd097501606fddbc7d22e5009d45e9e6cb7115ad109a46f8319a385bd4",
- "createdAt": "2021-08-03T18:17:57Z",
- "currency": "string",
- "feeCurrency": "string"
}
from | string Examples:
Start and inclusive date/time of the query |
to | string Examples:
End and inclusive date/time of the query |
{- "from": "2021-08-03T18:17:57Z",
- "to": "2021-08-03T18:17:57Z",
- "transferOutStats": {
- "CANCELLED BY MAKER": 110,
- "REJECTED BY AUTHORISER": 40,
- "FAILED": 367,
- "CONFIRMED": 20,
- "REJECTED BY SYSTEM": 126
}, - "transferInStats": {
- "UNLOCKED": 994,
- "REJECTED BY SYSTEM": 37,
- "PENDING UNLOCK": 38
}
}
{- "companyId": "ZTEST",
- "fromAddress": [
- "tb1qtx38mjl8gyg9gjk58tw88upytxwyxhmcqsv3le"
], - "toWallet": "ZTEST-NOBENF-849P8XKKAO",
- "toAddress": "2Mz5ZH9e6Q53QfK2E1Azaos3Vq62niibhc1",
- "transferId": "TRI-ZTEST-63Q4DZ0KJP",
- "transferStatus": "PENDING_UNLOCK",
- "amountLedger": 641400,
- "ledgerRef": "2f6e77f8c4313d0925f71acf19a659398115bdf903e3af06b3b1776e756c096f",
- "actionId": "TX_IN_ACTION-ZTEST-7LE2JCPZ3D",
- "method": "TRANSFER",
- "createdAt": "2021-08-03T18:17:57Z",
- "currency": "string"
}