# Dry run intents

This is an optional but highly recommended step of intent submission.

## Overview

Before you submit an intent, you can perform a dry run to try out the operation first. This simulates intent submission so you can understand its feasibility without the need to propose and sign an intent and go through the approval process of the policy engine.

Some examples of scenarios where a dry run can reveal a problem with the underlying intent are:

- An intent with the same UUID already exists.
- For new user creation, a user with the same public key is already registered in that domain, or the supplied public key is not in the right format.
- An account is created in an unsupported ledger.
- A transaction is blocked due to an incorrect destination address format, insufficient balance in the account, or insufficient fees.


Additionally, the dry run can return blockchain-specific fee information for a transaction, for example:

- Bitcoin: The size of the transaction in vBytes, and the estimated fee of the transaction.
- Ethereum: The amount of gas that a transaction will consume. This takes into account if the destination is a contract or a regular address and the content of the data field and is used to set the gas limit.
- XRPL: The current minimum cost in drops.
- Hedera: Additional token fees for tokens created using the Hedera Token Service, and whether those fees are to be paid by the sender or recipient.


## Prerequisites

Before you can dry run an intent, you need a JSON web token. For more information, see [Obtain a JSON web token](/products/custody/v1.26/api/get-started/jwt).

## Perform the dry run

To perform a dry run:

1. Prepare the request body, in the format shown in [Dry run and signature request body](/products/custody/v1.26/api/reference/intent-structure#dry-run-and-signature-request-body).
To get details of your author ID and associated domain ID, see [Check your user information](/products/custody/v1.26/api/get-started/register#check-your-user-information).
2. Call the [Perform a dry run for an intent](/products/custody/v1.26/api/reference/openapi/intents/intentdryrun) API operation.


If the result is not successful, you can find more information about the failure in the following fields, depending on the intent type:

- The `hint` field: Transaction intents.
- The `errors` field: Other intents.


### Examples

The following examples show dry requests and responses.

#### Dry run for an intent to create a user

**Request body:**


```json
{
    "author": {
        "id": "6ac20654-450e-29e4-65e2-1bdecb7db7c4",
        "domainId": "9067d363-6411-498b-a32b-15d230a86706"
    },
    "expiryAt": "2022-11-20T15:30:00.621Z",
    "targetDomainId": "9067d363-6411-498b-a32b-15d230a86706",
    "id": "cb1592c6-726d-45e6-8ca7-43b8115371e7",
    "payload": {
        "id": "cb1592c6-726d-45e6-8ca7-43b8115371e7",
        "alias": "hmz1@ripple.com",
        "publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0qPYorNOs+hRnB0tBt/YTHzh3vZHlFwdWUbYQbk3s5gWEw3JPK2J/a+ffK4cRwgGdHwzU2jfAC6X+LnDOEFeVA==",
        "roles": [
            "manager", "compliance", "director","operator"
        ],
        "lock": "Unlocked",
        "description": "",
        "customProperties": {},
        "type": "v0_CreateUser"
    },
    "description": "Intent",
    "customProperties": {},
    "type": "Propose"
}
```

**Response bodies:**

Success:


```json
{
	"success": true,
	"errors": null,
	"type": "v0_CreateUser"
}
```

Public key already in use:


```json
{
	"success": false,
	"errors": [
		"Public key MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0qPYorNOs+hRnB0tBt/YTHzh3vZHlFwdWUbYQbk3s5gWEw3JPK2J/a+ffK4cRwgGdHwzU2jfAC6X+LnDOEFeVA== already in use"
	],
	"type": "v0_CreateUser"
}
```

Public key in invalid format:


```json
{
	"success": false,
	"errors": [
		"Public key is invalid. It must be a DER encoded public key of the supported key type"
	],
	"type": "v0_CreateUser"
}
```

#### Dry run for an intent to create an account

**Request body:**


```json
{
    "author": {
        "id": "6ac20654-450e-29e4-65e2-1bdecb7db7c4",
        "domainId": "9067d363-6411-498b-a32b-15d230a86706"
    },
    "expiryAt": "2022-11-19T16:00:01.621Z",
    "targetDomainId": "9067d363-6411-498b-a32b-15d230a86706",
    "id": "6a8fc633-09fc-4d9b-ae41-33605cee995b",
    "payload": {
        "id": "6a8fc633-09fc-4d9b-ae41-33605cee995b",
        "alias": "test delete account",
        "providerDetails": {
            "vaultId": "00000000-0000-0000-0000-000000000000",
            "keyStrategy": "VaultHard",
            "type": "Vault"
        },
        "ledgerIds": ["avalanche-c-chain-testnet-fuji"],
        "lock": "Unlocked",
        "description": "Account for demo",
        "customProperties": {
            "securityZone":"Low"
        },
        "type": "v0_CreateAccount"
    },
    "description": "Bank account",
    "customProperties": {},
    "type": "Propose"
}
```

**Response bodies:**

Success:


```json
{
	"success": true,
	"errors": null,
	"type": "v0_CreateAccount"
}
```

Invalid vault:


```json
{
	"success": false,
	"errors": [
		"Vault 00000000-0000-0000-0000-000000000002 does not exist"
	],
	"type": "v0_CreateAccount"
}
```

Invalid ledger:


```json
{
	"success": false,
	"errors": [
		"Ledger avalanche-d-chain-testnet-fuji does not exist"
	],
	"type": "v0_CreateAccount"
}
```

#### Dry run for an intent to create a transaction

In the following transaction dry run examples, you can see the fee estimate and a hint about the outcome of submitting the intent.

**Request body:**


```json
{
    "author": {
        "id": "6ac20654-450e-29e4-65e2-1bdecb7db7c4",
        "domainId": "9067d363-6411-498b-a32b-15d230a86706"
    },
    "expiryAt": "2022-11-20T15:30:00.621Z",
    "targetDomainId": "9067d363-6411-498b-a32b-15d230a86706",
    "id": "cb1592c6-726d-45e6-8ca7-43b8115371e7",
    "payload": {
        "id": "f8b4c20f-58dc-4c89-adf0-6378d5b530b9",
        "accountId": "099e7fba-3f1e-4124-ad55-fd21328b222b",
        "parameters": {
            "destination": {
                "address": "rPZ8RvK3h8KewbMzr7RHFPSYmRA1a2wJGy",
                "type": "Address"
            },
            "amount": "439999955",
            "feeStrategy": {
                "drops": "5",
                "type": "SpecifiedAdditionalFee"
            },
            "maximumFee": "50",
            "sourceTag": 123456,
            "destinationTag": 132456,
            "memos": [
                {}
            ],
            "type": "XRPL"
        }
        "type": "v0_CreateTransactionOrder"
    },
    "description": "Intent new XRPL transaction",
    "customProperties": {},
    "type": "Propose"
}
```

**Response bodies:**

Success:


```json
{
  "result": {
    "type": "Success"
  },
  "estimate": {
    "minimumCostInDrops": "10",
    "type": "XRPL"
  }
}
```

Invalid address:


```json
{
  "result": {
    "hint": "InternalError",
    "reason": "Invalid address",
    "type": "Failure"
  },
  "estimate": {
    "hint": "InternalError",
    "reason": "Invalid address",
    "type": "Failure"
  }
}
```