Keep your settlement instructions up to date

Add a Stellar USDC wallet, make it the default for its currency, and retire a closed bank account so no order pays it.

This recipe adds a Stellar USDC wallet, makes it the default for its currency, and retires a closed bank account so that no order pays it.

Who it is for. A treasury team that receives FX proceeds into several of its own bank accounts and wallets, and needs to add, switch and retire them.

Status. Available.

Money example

Harbor Digital receives USDC on Stellar and naira at its bank.

  1. It adds a Stellar USDC wallet as an instruction, with its memo.
  2. It makes the new wallet the USDC default. The older USDC instruction stops being the default.
  3. Its old naira account closes, so it deletes that instruction. Gravv then refuses any order that still points at the instruction, instead of paying a closed account.

Before you start

A scoped key needs payee:create to create and update, and payee:delete to delete. Reading needs no permission.

Find out what is required

The create call names every missing field. The only network rule is that stellar needs memo. Gravv does not check wallet addresses, so copy them carefully.

Steps

1. Add a USDC wallet

curl --request POST \
 --url https://api.gravv.xyz/v1/settlement-instructions \
 --header 'Api-Key: <API_KEY>' \
 --header 'Idempotency-Key: e2d94b1c-95dc-4499-9b28-01b5ce372dd4' \
 --header 'Content-Type: application/json' \
 --data '
{
"instruction_type": "crypto_wallet",
"account_name": "Harbor Treasury Stellar",
"currency": "USDC",
"wallet_address": "GC3ONVVSIG2XZHHZCLJPDIR7ZAHR4IJ2AH34DFVDQVEFSPPX46DYJMJ2",
"network": "stellar",
"memo": "208117"
}
'
const response = await fetch("https://api.gravv.xyz/v1/settlement-instructions", {
method: "POST",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
"Idempotency-Key": "e2d94b1c-95dc-4499-9b28-01b5ce372dd4",
"Content-Type": "application/json",
},
body: JSON.stringify({
"instruction_type": "crypto_wallet",
"account_name": "Harbor Treasury Stellar",
"currency": "USDC",
"wallet_address": "GC3ONVVSIG2XZHHZCLJPDIR7ZAHR4IJ2AH34DFVDQVEFSPPX46DYJMJ2",
"network": "stellar",
"memo": "208117"
}),
});
console.log(response.status, await response.json());
import os

import requests

response = requests.post(
"https://api.gravv.xyz/v1/settlement-instructions",
headers={
    "Api-Key": os.environ["GRAVV_API_KEY"],
    "Idempotency-Key": "e2d94b1c-95dc-4499-9b28-01b5ce372dd4",
    "Content-Type": "application/json",
},
json={
    "instruction_type": "crypto_wallet",
    "account_name": "Harbor Treasury Stellar",
    "currency": "USDC",
    "wallet_address": "GC3ONVVSIG2XZHHZCLJPDIR7ZAHR4IJ2AH34DFVDQVEFSPPX46DYJMJ2",
    "network": "stellar",
    "memo": "208117",
},
)
print(response.status_code, response.json())

The response is the new instruction, with id 132c8884-fe71-46b0-8c73-2fdb614f7bb8, is_default false and status active. Gravv stores network as typed, so stellar, Stellar and XLM are three different values. Keep one lower-case spelling.

2. Make it the default

PATCH takes no Idempotency-Key.

curl --request PATCH \
 --url https://api.gravv.xyz/v1/settlement-instructions/132c8884-fe71-46b0-8c73-2fdb614f7bb8 \
 --header 'Api-Key: <API_KEY>' \
 --header 'Content-Type: application/json' \
 --data '
{
"is_default": true
}
'
const response = await fetch("https://api.gravv.xyz/v1/settlement-instructions/132c8884-fe71-46b0-8c73-2fdb614f7bb8", {
method: "PATCH",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"is_default": true
}),
});
console.log(response.status, await response.json());
import os

import requests

response = requests.patch(
"https://api.gravv.xyz/v1/settlement-instructions/132c8884-fe71-46b0-8c73-2fdb614f7bb8",
headers={
    "Api-Key": os.environ["GRAVV_API_KEY"],
    "Content-Type": "application/json",
},
json={
    "is_default": True,
},
)
print(response.status_code, response.json())

Gravv unsets the previous USDC default. Check with the list:

curl --request GET \
 --url 'https://api.gravv.xyz/v1/settlement-instructions?currency=USDC' \
 --header 'Api-Key: <API_KEY>'
const response = await fetch("https://api.gravv.xyz/v1/settlement-instructions?currency=USDC", {
method: "GET",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
},
});
console.log(response.status, await response.json());
import os

import requests

response = requests.get(
"https://api.gravv.xyz/v1/settlement-instructions?currency=USDC",
headers={
    "Api-Key": os.environ["GRAVV_API_KEY"],
},
)
print(response.status_code, response.json())

The list returns the default first, then the newest instructions.

3. Retire the old naira account

curl --request DELETE \
 --url https://api.gravv.xyz/v1/settlement-instructions/7e0161a9-34d6-4935-b764-d9eb3a7825f7 \
 --header 'Api-Key: <API_KEY>'
const response = await fetch("https://api.gravv.xyz/v1/settlement-instructions/7e0161a9-34d6-4935-b764-d9eb3a7825f7", {
method: "DELETE",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
},
});
console.log(response.status, await response.json());
import os

import requests

response = requests.delete(
"https://api.gravv.xyz/v1/settlement-instructions/7e0161a9-34d6-4935-b764-d9eb3a7825f7",
headers={
    "Api-Key": os.environ["GRAVV_API_KEY"],
},
)
print(response.status_code, response.json())
{
  "data": {
    "status": "deleted"
  },
  "error": null
}

The deleted instruction disappears from every read. Gravv refuses an order sent to it with bad destination: [400] invalid order destination. Orders already completed keep its id as destination_id. If it was the default, make another instruction the default, because Gravv does not promote one for you.

What can go wrong

Response Why Fix
400 memo is required for the stellar network: invalid input A Stellar wallet with no memo Add memo
400 wallet address is required for crypto wallets: invalid input / network is required for crypto wallets: invalid input A field is missing Add the missing field
400 settlement instruction <id>: resource not found The instruction is unknown, belongs to another business, or is already deleted (a second delete also returns this) List your instructions to get current ids
400 invalid id The path id is not a UUID Use the id from the list
A PATCH to change currency or instruction_type does nothing Both are fixed after create Delete the instruction and create a new one
A PATCH with "" does not clear a field An empty string keeps the value, so you cannot clear any field Create a new instruction
A PATCH accepts a Stellar network with no memo The update runs no checks Always send memo with a Stellar network
Two defaults for "the same" currency usdc and USDC are different currencies to the default rule Always send upper case
The list stops at 10 The page size is 10 unless you send items_per_page Send items_per_page

Webhooks you will receive

Gravv sends no webhooks for settlement instructions.

Testing in sandbox

You can test every step of this recipe in sandbox. Instructions are records only, and every response above is the same in sandbox.

Reference

Was this page helpful?