# Ripple Custody API


## Security

### httpAuth

Type: http
Scheme: bearer

### bearer-jwt

Type: http
Scheme: bearer
Bearer Format: JWT

## Download OpenAPI description

[Ripple Custody API](https://docs.ripple.com/_bundle/products/custody/@v1.36/devbox.yaml)

## Genesis

The **genesis** is the process by which an Harmonize environment is initialized. Upon system deployment, it is mandatory to define a **primary domain**, together with a suitable set of **users** and **policies**, such that the system can be operated using regular workflows. At minimum, one user and one policy must be defined, but a whole array of users and policies can be defined in order to render the Harmonize bootstrapping an atomic process.

The input request body contains two sections, namely the `rootDomainSetup` and the `cryptoSetup`. The former is akin to a regular new domain creation payload, while the latter is used to select the cryptographic algorithms to be used by the system.

Of particular importance, at genesis level, is the setting up of a **breakglass**, i.e., a protection mechanism against possible mis-usage of the policy engine that will allow to restore the system in case of wrong user manipulation. Enabling this feature is achieved by setting the property `governingStrategy` to `CoerceDescendants`. More information on this feature can be found in the developer documentation.

Calls to the genesis route are not authenticated, since the system has no active users at this stage.

Running Genesis on a new installation includes two properties in the `GenesisSucceeded` notary event:
- `genesis`: a data structure holding the notary signed original genesis payload
- `createdEntitiesReferences`: with key information on the data created

### Run the genesis

 - [POST /v1/genesis](https://docs.ripple.com/products/custody/v1.36/devbox/genesis/rungenesis.md)

## Domains

A **domain** defines a segregated set of entities (e.g., users, policies and accounts) with guaranteed isolation from each other. It also maintains the read access permissions of the domain users.

**Domains** are organized as part of a domain hierarchy, or tree: at the top of the hierarchy stands the root domain, which is defined at system genesis with the first **users** and **policies**. From the root domain down, subdomains can be created. The hierarchical structure ensures that any **intent** processed by the system must satisfy the **policies** of the **domain** in which the intent is to be executed, but also of all ancestors **domains** up to the root.

**Domain** segregation may be used to isolate the operations of different departments, subsidiaries, or possibly clients, of the custodian and provide them with the ability to define their own respective users, policies, and accounts independently.

The locking of a **domain** prevents the execution of any **intent** within the **domain** or any of its subdomains.

### Get domain details

 - [GET /v1/domains/{domainId}](https://docs.ripple.com/products/custody/v1.36/devbox/domains/getdomain.md)

### List domains

 - [GET /v1/domains](https://docs.ripple.com/products/custody/v1.36/devbox/domains/getdomains.md)

## Vaults

A **vault** is a component that maintains secret key material and is responsible for the creation and signing process of outgoing ledger transactions.

A **vault** executes **transaction orders** once they are fully approved and delivers the signed ledger **transaction** to the system for broadcast. A single instance of *Harmonize* can hold multiple **vaults**, which may provide complementary features (e.g., various distributed ledger protocols), key stores (e.g., different hardware vendors or multi-party computation-based algorithms), or key isolation (e.g., connected, or air-gapped). For example, a system can leverage a hot vault (for hot accounts) and an air-gapped vault (for cold accounts). **Accounts** within the system are associated with specific vaults.

The registration of the public key of a vault, `publicKey`, allows the system to verify any information returned by the vault.

The locking of a **vault** prevents the execution of any **transaction order** related to the specific **vault**.

### List vaults

 - [GET /v1/vaults](https://docs.ripple.com/products/custody/v1.36/devbox/vaults/getvaults.md)

### Get vault details

 - [GET /v1/vaults/{vaultId}](https://docs.ripple.com/products/custody/v1.36/devbox/vaults/getvault.md)

### Export prepared operations

 - [GET /v1/vaults/{vaultId}/operations/prepared](https://docs.ripple.com/products/custody/v1.36/devbox/vaults/paths/~1v1~1vaults~1%7Bvaultid%7D~1operations~1prepared/get.md): Export prepared operations

### Import signed operations

 - [POST /v1/vaults/operations/signed](https://docs.ripple.com/products/custody/v1.36/devbox/vaults/paths/~1v1~1vaults~1operations~1signed/post.md): Import signed operations

## Ledgers

A **ledger** is an accounting system, such as a blockchain, that is supported and tracked.

A **ledger** is defined by its `parameters`, which describe its protocol and configuration. For any supported protocol, multiple ledgers instances may be registered. This allows derivative ledgers, such as testnets, forks, or permissioned instances to be connected to *Harmonize* natively. 

### List ledgers

 - [GET /v1/ledgers](https://docs.ripple.com/products/custody/v1.36/devbox/ledgers/getledgers.md)

### Get ledger details

 - [GET /v1/ledgers/{ledgerId}](https://docs.ripple.com/products/custody/v1.36/devbox/ledgers/getledger.md)

### Get ledger's fee details

 - [GET /v1/ledgers/{ledgerId}/fees](https://docs.ripple.com/products/custody/v1.36/devbox/ledgers/getledgerfees.md)

### [Ethereum] Process contract call

 - [POST /v1/ledgers/{ledgerId}/ethereum/call](https://docs.ripple.com/products/custody/v1.36/devbox/ledgers/processethereumcontractcall.md)

### Get trusted ledger details

 - [GET /v1/trusted-ledgers/{ledgerId}](https://docs.ripple.com/products/custody/v1.36/devbox/ledgers/gettrustedledger.md)

### List trusted ledgers

 - [GET /v1/trusted-ledgers](https://docs.ripple.com/products/custody/v1.36/devbox/ledgers/gettrustedledgers.md)

## Tickers

A **ticker** defines a detected currency and its respective symbol, number and parameters.

In particular, the number of `decimals` of a particular ticker is critical to the proper encoding of transfer amounts.

### List tickers

 - [GET /v1/tickers](https://docs.ripple.com/products/custody/v1.36/devbox/tickers/gettickers.md)

### Get ticker details

 - [GET /v1/tickers/{tickerId}](https://docs.ripple.com/products/custody/v1.36/devbox/tickers/getticker.md)

## Accounts

An **account** tracks the balance(s) and transactions history of a data source. In the context of a distributed ledger, it relies on a set of keys and addresses provided by its **vault**.

For multi-address ledger protocols, accounts may generate and track multiple separate addresses transparently. For multi-currency protocols, a single account may have multiple balances corresponding to each respective asset owned by the **account**.

An **account** ensures the quarantine of all incoming transfers, such that their release is suject to a formal **policy**. It also manages balance reserves to ensure fully approved transaction orders become executable with little delay.

The locking of an **account** prevents the execution of any **transaction order** related to the specific **account**, as well as the release of quarantined incoming **transfers**.

### List accounts

 - [GET /v1/domains/{domainId}/accounts](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/getaccounts.md)

### Get address from all generated addresses across domains

 - [GET /v1/addresses](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/getalldomainsaddresses.md)

### Get account details

 - [GET /v1/domains/{domainId}/accounts/{accountId}](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/getaccount.md)

### Retrieve all generated addresses

 - [GET /v1/domains/{domainId}/accounts/{accountId}/addresses](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/getaddresses.md)

### Generate new account external address

 - [POST /v1/domains/{domainId}/accounts/{accountId}/addresses/{ledgerId}](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/generatenewexternaladdress.md)

### Retrieve account address

 - [GET /v1/domains/{domainId}/accounts/{accountId}/addresses/{accountAddressId}](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/getaccountaddress.md)

### Get account balances

 - [GET /v1/domains/{domainId}/accounts/{accountId}/balances](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/getaccountbalances.md)

### Update account balances forcefully

 - [POST /v1/domains/{domainId}/accounts/{accountId}/balances/refresh](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/forceupdateaccountbalances.md)

### List manifests

 - [GET /v1/domains/{domainId}/accounts/{accountId}/manifests](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/getmanifests.md)

### Get manifest details

 - [GET /v1/domains/{domainId}/accounts/{accountId}/manifests/{manifestId}](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/getmanifest.md)

### Generate new account external address (deprecated)

 - [POST /v1/domains/{domainId}/accounts/{accountId}/addresses](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/generatenewexternaladdressdeprecated.md)

### Retrieve latest external address (deprecated)

 - [GET /v1/domains/{domainId}/accounts/{accountId}/addresses/latest](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/getlatestaddress.md)

### Get account confirmed balance for a specific ticker (deprecated)

 - [GET /v1/domains/{domainId}/accounts/{accountId}/confirmed-balance/{tickerId}](https://docs.ripple.com/products/custody/v1.36/devbox/accounts/getaccountconfirmedbalance.md)

## External accounts

**External account** APIs are used to connect to a third party custodian, typically a trading venue, to instruct trading orders directly from Harmonize. The following calls allow to setup a connection with an external provider, list the external accounts and their balances.

### Connect an external account provider

 - [POST /v1/domains/{domainId}/external-accounts/providers](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1providers/post.md): Connect an external account provider

### List external account provider connections

 - [GET /v1/domains/{domainId}/external-accounts/providers](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1providers/get.md): List external account provider connections

### Update an external account provider connection

 - [POST /v1/domains/{domainId}/external-accounts/providers/{connectionId}](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1providers~1%7Bconnectionid%7D/post.md): Update an external account provider connection

### Get external account provider connections

 - [GET /v1/domains/{domainId}/external-accounts/providers/{connectionId}](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1providers~1%7Bconnectionid%7D/get.md): Get external account provider connections

### Disconnect an external account provider

 - [DELETE /v1/domains/{domainId}/external-accounts/providers/{connectionId}](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1providers~1%7Bconnectionid%7D/delete.md): Disconnect an external account provider

### List external accounts

 - [GET /v1/domains/{domainId}/external-accounts](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts/get.md): List external accounts

### Get external account details

 - [GET /v1/domains/{domainId}/external-accounts/{externalAccountId}](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1%7Bexternalaccountid%7D/get.md): Get external account details

### Get external account balances

 - [GET /v1/domains/{domainId}/external-accounts/{externalAccountId}/balances](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1%7Bexternalaccountid%7D~1balances/get.md): Get external account balances

### Retrieve latest external address

 - [GET /v1/domains/{domainId}/external-accounts/{externalAccountId}/addresses/latest](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1%7Bexternalaccountid%7D~1addresses~1latest/get.md): Retrieve latest external address

### Retrieve all generated addresses

 - [GET /v1/domains/{domainId}/external-accounts/{externalAccountId}/addresses](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1%7Bexternalaccountid%7D~1addresses/get.md): Retrieve all generated addresses

### Generate new account external address

 - [POST /v1/domains/{domainId}/external-accounts/{externalAccountId}/addresses](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1%7Bexternalaccountid%7D~1addresses/post.md): Generate new account external address

### Retrieve account external address

 - [GET /v1/domains/{domainId}/external-accounts/{externalAccountId}/addresses/{externalAccountAddressId}](https://docs.ripple.com/products/custody/v1.36/devbox/external-accounts/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1%7Bexternalaccountid%7D~1addresses~1%7Bexternalaccountaddressid%7D/get.md): Retrieve account external address

## Endpoints

An **endpoint** associates ledger addresses with human-readable aliases to keep track of whitelisted and blacklisted addresses. It is also used to register smart contract addresses and possibly associate an ABI to them.

An **endpoint** may be used as a destination to a **transaction order**, therefore acting as a form of address book entry. *Harmonize* ensures a secure mapping of the **endpoint** to its underlying address when preparing the **transaction** for execution.

An **endpoint** may also be used to validate the destination of a **transaction order** within a policy and to trigger specific approval workflows depending on the attributes of the **endpoint**. For instance, a **policy** may enforce a simplified approval workflow when the destination **endpoint** is marked as whitelisted, or may require an exceptional set of approvers when it is marked as blacklisted.

Lastly, endpoints may also be used to attach meta information to an address. This is the case of smart contract addresses, for instance, which may be attached to the interface, or ABI, of the contract, such that the methods and properties of the contract are known to the system.

The locking of an **endpoint** prevents its use in any context.

### List endpoints

 - [GET /v1/domains/{domainId}/endpoints](https://docs.ripple.com/products/custody/v1.36/devbox/endpoints/getendpoints.md)

### Get endpoint details

 - [GET /v1/domains/{domainId}/endpoints/{endpointId}](https://docs.ripple.com/products/custody/v1.36/devbox/endpoints/getendpoint.md)

## Transactions

A **transaction order** is an order to transfer assets or request an operation on the ledger. In the simplest case, it relates to the transfer of a native cryptocurrency; in more advanced cases, it can apply to the execution of smart contract methods and other on-ledger features.

**Transaction orders** may differ from one ledger protocol to another, but they at least define the account origin, and normally have an amount and a destination address; for some protocols, a single transaction may include multiple destinations and amounts, possibly denominated in various currencies.

**Transaction orders** rely on property `parameters` to define ledger-specific transaction order parameters.

We present below the transaction order parameters for Bitcoin:
 - `outputs`: sequence of pairs of destination and amount;
 - `feeStrategy`: fee calculation strategy, which may be `Low`, `Medium` or `High`; the actual fee amount corresponding to the selected strategy is automatically set by the system at execution time based on a network metrics;
 - `maximumFee`: maximum fee the user is willing to pay to execute the transaction; in rare occasions, *Harmonize* may decide to rebroadcast a transaction with higher fees to ensure inclusion within the ledger, as long as `maximumFee` has not been reached.

For an exhaustive list corresponding to each respective ledger protocol, we refer to the reference manual.

*Harmonize* supports multiple types of destinations for **transaction orders**:
 - ledger address: a ledger address is a protocol-level address, whose format may differ from one ledger protocol to another;
 - account: an account destination is an **account** `id`, which is guaranteed to implicitly resolve to an address of the account; for protocols supporting multiple addresses per account, no guarantee is provided over which account address the resolution leads to;
 - endpoint: an endpoint destination is an **endpoint** `id`, which is guaranteed to implicitly resolve to the address of the endpoint.

Once a **transaction order** is fully approved the order becomes executable. The corresponding **vault** may capture the pending **transaction order** and build and sign a corresponding ledger transaction.

**Transactions** are incoming or outgoing ledger transactions that have been detected on the ledger or shall be broadcast. **Transfers** are the financial representation of their corresponding **transactions**. 

### List transaction orders

 - [GET /v1/domains/{domainId}/transactions/orders](https://docs.ripple.com/products/custody/v1.36/devbox/transactions/getorders.md)

### Get transaction order details

 - [GET /v1/domains/{domainId}/transactions/orders/{transactionOrderId}](https://docs.ripple.com/products/custody/v1.36/devbox/transactions/getorder.md)

### List transfers

 - [GET /v1/domains/{domainId}/transactions/transfers](https://docs.ripple.com/products/custody/v1.36/devbox/transactions/gettransfers.md)

### Get transfer details

 - [GET /v1/domains/{domainId}/transactions/transfers/{transferId}](https://docs.ripple.com/products/custody/v1.36/devbox/transactions/gettransfer.md)

### List transactions

 - [GET /v1/domains/{domainId}/transactions](https://docs.ripple.com/products/custody/v1.36/devbox/transactions/gettransactions.md)

### Get transaction details

 - [GET /v1/domains/{domainId}/transactions/{transactionId}](https://docs.ripple.com/products/custody/v1.36/devbox/transactions/gettransaction.md)

### Dry run a transaction order

 - [POST /v1/domains/{domainId}/transactions/dry-run](https://docs.ripple.com/products/custody/v1.36/devbox/transactions/dryruntransaction.md)

## Intents

An **intent** represents a request to execute an action within the system, which shall eventually be executed if fully approved. In *Harmonize*, all security-critical operations follow the below execution lifecycle:
1. a user submits a properly signed intent to execute an action;
2. *Harmonize* browses through the **policies**, sorted by `rank`, and selects the first **policy** with matching `intentTypes` and `condition`;
3. *Harmonize* validates that the **policy** authorizes the author of the intent to submit it and sets the full approval `workflow` required for execution;
4. *Harmonize* waits for the required quorum of approvals as defined in the selected **policy** `workflow`;
5. Once fully approved, *Harmonize* executes the intent and mutates the state of the system, possibly triggering the execution of a side effect such as the processing of a transaction.

The author of an intent defines, in particular, the following fields:
- `payload`, which sets the `type` of the intent and the details of the operation to process;
- `expiry`, which sets an expiration time to the intent;
- `targetDomainId`, which sets the domain in which to execute the intent (either in the current domain or within a descendant domain);
- `type`, which defines whether the intent is an original submission (`Propose`), an intention to approve an existing intent (`Approve`) or an intention to reject an existing intent (`Reject`).

There exist four intent types for most entities in the system, as prefixed by:
- **Create** to create an entity of a given type;
- **Update** to update the definition of an entity;
- **Lock** to lock an entity;
- **Unlock** to unlock an entity.

Exceptions exist, such as for the release of quarantined **transfers**, which has its dedicated intent called **ReleaseQuarantinedTransfers**.

A generic intent, named **NotarizeData**, allows the submission of intents not related to internal processes of *Harmonize*. Such **intents** may be used to trigger external effects to extend the capabilities of the system, such as to initiate fiat payment orders or trading orders.

### Propose an intent

 - [POST /v1/intents](https://docs.ripple.com/products/custody/v1.36/devbox/intents/createintent.md)

### Approve an intent

 - [POST /v1/intents/approve](https://docs.ripple.com/products/custody/v1.36/devbox/intents/approveintent.md)

### Reject an intent

 - [POST /v1/intents/reject](https://docs.ripple.com/products/custody/v1.36/devbox/intents/rejectintent.md)

### List intents

 - [GET /v1/domains/{domainId}/intents](https://docs.ripple.com/products/custody/v1.36/devbox/intents/getintents.md)

### Get intent details

 - [GET /v1/domains/{domainId}/intents/{intentId}](https://docs.ripple.com/products/custody/v1.36/devbox/intents/getintent.md)

### Get remaining users

 - [GET /v1/domains/{domainId}/intents/{intentId}/remaining-users](https://docs.ripple.com/products/custody/v1.36/devbox/intents/getremainingusers.md): This API will return the remaining user IDs able to approve for the currently open step of the intent approval process.

### Perform a dry-run for given intent payload

 - [POST /v1/intents/dry-run](https://docs.ripple.com/products/custody/v1.36/devbox/intents/intentdryrun.md)

## Policies

A **policy** is an operational rule defining the required approval `workflow` for the execution of a particular **intent**. It regulates user entitlements and, if properly configured, ensures that the governance is properly distributed and the system has no single point of compromise. 

In particular, **policies** regulate the approval `workflow` for the creation and update of
- **domains**,
- **users** and their related roles,
- **policies** and their related approval workflows (i.e., creating and updating **policies** is itself subject to a **policy**),
- **accounts**,
- **vaults**,
- **endpoints**,
- **transaction orders.**

**Policies** may also regulate other interactions with the system, such as the release of quarantined, incoming **transfers**.

**Policies** may be refined to cover precise use cases using the property `condition`. A `condition` can be any combination of predicates over the context parameters, which are injected into the evaluation context of the condition at runtime. Such parameters depend on the intent type and other factors. In particular, an **intent** related to a **transaction order** includes information such as the amount, destination(s) address, and source account of the order; an **intent** related to a **user** includes the roles of the user, its alias, etc. For more information about context parameters, we refer to the reference manual.

Because there may be many **policies**, multiple of which may apply to a given **intent**, **policies** are sorted according to property `rank` such that the highest rank policy to match a particular intent is selected.

**Policies** may be defined such as to regulate **intents** within the current domain, or **intents** initiated within a subdomain, or both, with property `scope`. We refer to the reference manual for more information on supervision and governance delegation.

The property `workflow` defines the approval workflow that should be satisfied for an intent to be approved. Each **policy** may have a different approval workflow, which consists in a sequence of steps, each composed of a combination of user roles. For an intent to be executed, all steps of the workflow shall sequentially receive enough approvals (quorum) to evaluate positively. The quorum can't exceed 2000 approvals per step. A single rejection fails the execution of the intent.

The locking of a **policy** ignores it entirely in the process of the policy selection.

### List policies

 - [GET /v1/domains/{domainId}/policies](https://docs.ripple.com/products/custody/v1.36/devbox/policies/getpolicies.md)

### Get policy details

 - [GET /v1/domains/{domainId}/policies/{policyId}](https://docs.ripple.com/products/custody/v1.36/devbox/policies/getpolicy.md)

## Users

A **user** is a human or technical consumer of the *Harmonize* service. 

A user is associated with a public key, which is registered into the system alongside a set of roles. The roles relate to the permissions a user has to access the various entities within the system (as defined within a particular **domain**) as well as to propose, approve and reject the execution of intents (as defined by the approval workflow of a policy).

Users have, in particular, the following properties:
 - `publicKey`: the public key used to authenticate any user request
 - `roles`: a collection of human-readable strings defining the roles of a user

The private key corresponding to `publicKey` is generated on the user-side, either within the mobile approval terminal or programmatically, and is never communicated to the system. We emphasize here that a user key pair is merely used to authenticate the user and approve the execution of **intents**; it is unrelated to the account keys securing the accounts on the ledger. The loss of a **user** key is dealt with by locking the user and creating a new user with a rotated key.

The locking of a **user** prevents its access to the platform entirely.

### List users

 - [GET /v1/domains/{domainId}/users](https://docs.ripple.com/products/custody/v1.36/devbox/users/getusers.md)

### Get known users roles

 - [GET /v1/domains/{domainId}/users/roles](https://docs.ripple.com/products/custody/v1.36/devbox/users/getknownuserroles.md)

### Get user details

 - [GET /v1/domains/{domainId}/users/{userId}](https://docs.ripple.com/products/custody/v1.36/devbox/users/getuser.md)

### List users belonging to the same public key

 - [GET /v1/me](https://docs.ripple.com/products/custody/v1.36/devbox/users/getme.md)

## User invitations

**User invitations** are an alternative method to create users. With a user invitation, there is no need for the user to manually share its public key as the process is fully automated in the backend. Moreover it is possible to create invitations that have an expiration date.

### List user invitations

 - [GET /v1/domains/{domainId}/users/invitations](https://docs.ripple.com/products/custody/v1.36/devbox/user-invitations/paths/~1v1~1domains~1%7Bdomainid%7D~1users~1invitations/get.md): List user invitations

### Create a user invitation

 - [POST /v1/domains/{domainId}/users/invitations](https://docs.ripple.com/products/custody/v1.36/devbox/user-invitations/paths/~1v1~1domains~1%7Bdomainid%7D~1users~1invitations/post.md): Create a user invitation

### Get user invitation details

 - [GET /v1/domains/{domainId}/users/invitations/{id}](https://docs.ripple.com/products/custody/v1.36/devbox/user-invitations/paths/~1v1~1domains~1%7Bdomainid%7D~1users~1invitations~1%7Bid%7D/get.md): Get user invitation details

### Cancel a user invitation

 - [POST /v1/domains/{domainId}/users/invitations/{id}/cancel](https://docs.ripple.com/products/custody/v1.36/devbox/user-invitations/paths/~1v1~1domains~1%7Bdomainid%7D~1users~1invitations~1%7Bid%7D~1cancel/post.md): Cancel a user invitation

### Renew a user invitation

 - [POST /v1/domains/{domainId}/users/invitations/{id}/renew](https://docs.ripple.com/products/custody/v1.36/devbox/user-invitations/paths/~1v1~1domains~1%7Bdomainid%7D~1users~1invitations~1%7Bid%7D~1renew/post.md): Renew a user invitation

### Complete a user invitation

 - [POST /v1/domains/{domainId}/users/invitations/{id}/complete](https://docs.ripple.com/products/custody/v1.36/devbox/user-invitations/paths/~1v1~1domains~1%7Bdomainid%7D~1users~1invitations~1%7Bid%7D~1complete/post.md): Complete a user invitation

### Fill a user invitation

 - [POST /v1/users/invitations/{idOrCode}](https://docs.ripple.com/products/custody/v1.36/devbox/user-invitations/paths/~1v1~1users~1invitations~1%7Bidorcode%7D/post.md): Fill a user invitation

### Get public data of user invitation

 - [GET /v1/users/invitations/{idOrCode}](https://docs.ripple.com/products/custody/v1.36/devbox/user-invitations/paths/~1v1~1users~1invitations~1%7Bidorcode%7D/get.md): Get public data of user invitation

## Events

An **event** is a notification payload generated through user actions, system signals, and ledger updates.

Events are the notification payloads generated through user actions, system signals, and ledger updates.

Event payloads follow a common pattern including the following fields:
- `id`, a unique identifier for the event,
- `domainId`, a reference to the domain where the event has been issued,
- `sequenceNumber`, a strictly increasing sequence number (but possibly non contiguous),
- `savedAt`, a timestamp, and
- `payload`, additional information depending on the event type.

### List events

 - [GET /v1/domains/{domainId}/events](https://docs.ripple.com/products/custody/v1.36/devbox/events/getevents.md)

## Requests

A **request** allows to follow the progress of a user request and identify a possible failure. 

Most requests to the system return a `requestId` in the response body, which may be used to inquire on the status of the request.

It is also possible and encouraged to provide a user-defined requestId using the `requestId` HTTP header when submitting intents or when approving/refusing them, this has several advantages:
- If the connection is interrupted between the request and the response the `requestId` will still be known by the caller, which can then check if the request has been submitted to Harmonize or not
- If the caller retries to submit another request with an already-used `requestId`, Harmonize will prevent this by returning an error, in order to avoid the involuntary replay of a request

**Users** satisfying any of the below conditions are allowed to read a **request** status:
- user is the originator of the request (even if it does not have a read access to `requests`)
- user is in the originator domain and has a role granting him read access to `requests`
- user is in the target domain and has a role granting him read access to `requests`

A **request** will return, in particular, the following fields:
- `lastModifiedAt`, which tracks the last update timestamp of the request;
- `status`, which may be `Processing`, `Succeeded` or `Failed`; a `Failed` status also exposes an additional field detailing the failure reason.
- `history`, which tracks all the intermediate steps of the user request, with details regarding the source component, the status, an eventual hint in case of failure, and a timestamp;

### Get request state

 - [GET /v1/domains/{domainId}/requests/{requestId}](https://docs.ripple.com/products/custody/v1.36/devbox/requests/getrequeststate.md)

### Get all user requests state

 - [GET /v1/me/requests](https://docs.ripple.com/products/custody/v1.36/devbox/requests/getalluserrequestsstate.md)

### Get all user requests state in domain

 - [GET /v1/domains/{domainId}/requests](https://docs.ripple.com/products/custody/v1.36/devbox/requests/getalluserrequestsstateindomain.md)

## SystemProperties

A **SystemProperty** defines a key value secure collection dedicated to store system-wide values.
There are system-defined ones and user-defined ones, access to all is available by properties API. 
User defined one could be created and updated by using SetSystemProperty indent.  

### List system properties

 - [GET /v1/properties](https://docs.ripple.com/products/custody/v1.36/devbox/systemproperties/getsystemproperties.md)

## External account trading

**External account** refers to account held at exchanges or sub-custodians. The trading APIs allow to obtaining pairs and pricing offered by the exchange.

### Get available trade pairs

 - [GET /v1/domains/{domainId}/external-accounts/providers/{connectionId}/pairs](https://docs.ripple.com/products/custody/v1.36/devbox/external-account-trading/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1providers~1%7Bconnectionid%7D~1pairs/get.md): Get available trade pairs

### Get balance directly from a connection and a speci

 - [GET /v1/domains/{domainId}/external-accounts/providers/{connectionId}/balances](https://docs.ripple.com/products/custody/v1.36/devbox/external-account-trading/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1providers~1%7Bconnectionid%7D~1balances/get.md): Get balance directly from a connection and a specified ticker name

### Get pair price

 - [GET /v1/domains/{domainId}/external-accounts/providers/{connectionId}/pairs/{baseExternalTickerName}/{quoteExternalTickerName}/price](https://docs.ripple.com/products/custody/v1.36/devbox/external-account-trading/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1providers~1%7Bconnectionid%7D~1pairs~1%7Bbaseexternaltickername%7D~1%7Bquoteexternaltickername%7D~1price/get.md): Get pair price

## External account transactions

**External account** refers to account held at exchanges or sub-custodians. The transactions APIs allow to monitoring and listing of orders and transactions that are instructed to the sub-custodian.

### Get external account orders

 - [GET /v1/domains/{domainId}/external-accounts/transactions/orders](https://docs.ripple.com/products/custody/v1.36/devbox/external-account-transactions/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1transactions~1orders/get.md): Get external account orders

### Get external account transfers

 - [GET /v1/domains/{domainId}/external-accounts/transactions/transfers](https://docs.ripple.com/products/custody/v1.36/devbox/external-account-transactions/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1transactions~1transfers/get.md): Get external account transfers

### Transaction dry run

 - [POST /v1/domains/{domainId}/external-accounts/transactions/dry-run](https://docs.ripple.com/products/custody/v1.36/devbox/external-account-transactions/paths/~1v1~1domains~1%7Bdomainid%7D~1external-accounts~1transactions~1dry-run/post.md): Transaction dry run

## VirtualAccounting

### Get virtual ledgers

 - [GET /v1/domains/{domainId}/virtual-ledgers](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers/get.md): Get virtual ledgers

### Create a virtual ledger

 - [POST /v1/domains/{domainId}/virtual-ledgers](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers/post.md): Create a virtual ledger

### Get virtual ledger

 - [GET /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D/get.md): Get virtual ledger

### Update virtual ledger

 - [PUT /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D/put.md): Update virtual ledger

### Get virtual ledger balances

 - [GET /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}/balances](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D~1balances/get.md): Get virtual ledger balances

### Get virtual ledger accounts

 - [GET /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}/accounts](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D~1accounts/get.md): Get virtual ledger accounts

### Create a virtual account

 - [POST /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}/accounts](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D~1accounts/post.md): Create a virtual account

### Update a virtual account

 - [PUT /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}/accounts/{accountId}](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D~1accounts~1%7Baccountid%7D/put.md): Update a virtual account

### Get virtual account balances

 - [GET /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}/accounts/{accountId}/balances](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D~1accounts~1%7Baccountid%7D~1balances/get.md): Get virtual account balances

### Assign a deposit identification source to an accou

 - [POST /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}/accounts/{accountId}/deposit-identification-sources](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D~1accounts~1%7Baccountid%7D~1deposit-identification-sources/post.md): Assign a deposit identification source to an account

### Get virtual account addresses

 - [GET /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}/accounts/{accountId}/addresses](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D~1accounts~1%7Baccountid%7D~1addresses/get.md): Get virtual account addresses

### Get virtual ledger's operations

 - [GET /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}/operations](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D~1operations/get.md): Get virtual ledger's operations

### Create operation

 - [POST /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}/operations](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D~1operations/post.md): Create operation

### Get transfers

 - [GET /v1/domains/{domainId}/virtual-ledgers/{virtualLedgerId}/transfers](https://docs.ripple.com/products/custody/v1.36/devbox/virtualaccounting/paths/~1v1~1domains~1%7Bdomainid%7D~1virtual-ledgers~1%7Bvirtualledgerid%7D~1transfers/get.md): Get transfers

## Compliance

Compliance APIs enable the creation of compliance-related domains, integration with compliance providers, management of risk score configurations, and execution of compliance analyses. They facilitate the creation of compliance policies, as well as the management of compliance users and agents to automate compliance checks effectively.

### Enables or disables the preview screening for an existing provider connection

 - [PUT /v1/domains/{domainId}/compliance/providers/{provider}/toggle-preview-screening](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/togglepreviewscreening.md)

### Pause/unpause an existing external provider connection

 - [PUT /v1/domains/{domainId}/compliance/providers/{provider}/pause-connection](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/pauseproviderconnection.md)

### Retrieves configuration steps and provider connection status for the give domain

 - [GET /v1/domains/{domainId}/compliance/providers](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/getallprovidersfordomain.md)

### Connects different external providers with Custody

 - [POST /v1/domains/{domainId}/compliance/providers](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/connectprovider.md)

### Retrieves screening rules for connected provider of the given domain

 - [GET /v1/domains/{domainId}/compliance/providers/{provider}/screening-rules](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/getscreeningrulesfordomainandprovider.md)

### Creates screening rules for connected provider of the given domain

 - [POST /v1/domains/{domainId}/compliance/providers/{provider}/screening-rules](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/configurescreeningrulesfordomainandprovider.md)

### Create Compliance Policy Payload

 - [POST /v1/domains/{domainId}/compliance/policy](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/createpolicypayload.md)

### Creates Domain payload

 - [POST /v1/domains/{domainId}/compliance/domain](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/createdomainpayload.md)

### Delete compliance domain

 - [DELETE /v1/domains/{domainId}/compliance/domain](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/deletecompliancedomain.md)

### Check if compliance domain creation/injection is allowed

 - [POST /v1/domains/{domainId}/compliance/domain/validation](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/validatecompliancedomaincreation.md)

### Retrieves compliance analysis against all established external providers.

 - [POST /v1/domains/{domainId}/compliance/analysis](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/analysis.md)

### Performs a preview analysis of the wallet

 - [POST /v1/domains/{domainId}/compliance/analysis/preview](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/previewanalysis.md)

### Gets Exception role for the domain

 - [GET /v1/domains/{domainId}/compliance/transactionType/{transactionType}/exception-role](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/getexceptionrole.md)

### Retrieves connected provider connection details for the given domain

 - [GET /v1/domains/{domainId}/compliance/provider-connection](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/getallproviderconnectionfordomain.md)

### Gets Compliance policy for the domain

 - [GET /v1/domains/{domainId}/compliance/policy/{policyType}/transaction/{transactionType}](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/getpolicy.md)

### Deletes provider connection and screening rules for the given domain & provider

 - [DELETE /v1/domains/{domainId}/compliance/providers/{provider}](https://docs.ripple.com/products/custody/v1.36/devbox/compliance/deleteproviderconnectionandscreeningrules.md)

## Event Distribution Service

Event Distribution Service (EDS) APIs

### getAllChannels

 - [GET /v1/domains/{domainId}/channels](https://docs.ripple.com/products/custody/v1.36/devbox/event-distribution-service/getallchannels.md)

### createChannel

 - [POST /v1/domains/{domainId}/channels](https://docs.ripple.com/products/custody/v1.36/devbox/event-distribution-service/createchannel.md)

### testChannel

 - [POST /v1/domains/{domainId}/channels/{channelId}/test](https://docs.ripple.com/products/custody/v1.36/devbox/event-distribution-service/testchannel.md)

### getChannel

 - [GET /v1/domains/{domainId}/channels/{channelId}](https://docs.ripple.com/products/custody/v1.36/devbox/event-distribution-service/getchannel.md)

### deleteChannel

 - [DELETE /v1/domains/{domainId}/channels/{channelId}](https://docs.ripple.com/products/custody/v1.36/devbox/event-distribution-service/deletechannel.md)

### updateChannel

 - [PATCH /v1/domains/{domainId}/channels/{channelId}](https://docs.ripple.com/products/custody/v1.36/devbox/event-distribution-service/updatechannel.md)

### getAllChannelEvents

 - [GET /v1/domains/{domainId}/channels/{channelId}/events](https://docs.ripple.com/products/custody/v1.36/devbox/event-distribution-service/getallchannelevents.md)

### getEvent

 - [GET /v1/domains/{domainId}/channels/{channelId}/events/{eventId}](https://docs.ripple.com/products/custody/v1.36/devbox/event-distribution-service/getevent.md)

### getAllEvents

 - [GET /v1/domains/{domainId}/channels/events](https://docs.ripple.com/products/custody/v1.36/devbox/event-distribution-service/getallevents.md)

## Backups

### Get Backup information

 - [GET /v1/backups/{backupId}](https://docs.ripple.com/products/custody/v1.36/devbox/backups/getbackup.md)

### List Backups

 - [GET /v1/backups](https://docs.ripple.com/products/custody/v1.36/devbox/backups/getbackups.md)

### Get Backup trusted entity details

 - [GET /v1/backups/{backupId}/trusted-entity](https://docs.ripple.com/products/custody/v1.36/devbox/backups/getbackuptrustedentity.md)

## TrustedPublicKeys

### List trusted-collection public keys

 - [GET /v1/trusted-public-keys/trusted-collection](https://docs.ripple.com/products/custody/v1.36/devbox/trustedpublickeys/gettrustedpublickeystrustedcollection.md)

### List api public keys

 - [GET /v1/trusted-public-keys/api](https://docs.ripple.com/products/custody/v1.36/devbox/trustedpublickeys/gettrustedpublickeysapi.md)

### List messages public keys

 - [GET /v1/trusted-public-keys/messages](https://docs.ripple.com/products/custody/v1.36/devbox/trustedpublickeys/gettrustedpublickeysmessages.md)

