> ## Documentation Index
> Fetch the complete documentation index at: https://docs.primevault.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Approvals

> Transactions, vaults, contacts, and bank accounts you create or change through the API wait for your API user's approval. Get the approval message, sign it, and submit the action.

Creating or changing certain resources through the API opens a change request. The change does not take effect until your API user approves it. Every change request uses the same two endpoints: [Get Approval Message](/approvals/get-approval-message) and [Submit Approval Action](/approvals/submit-approval-action).

## What needs approval

For each change below, pass the `id` from the create or update response as `entityId`.

| Change | Endpoint | SDK: create and approve |
| - | - | - |
| Create a transaction | Any transaction create call. See [Transactions](#transactions). | See [Transactions](#transactions). |
| Create a vault | [Create a Vault](/accounts-and-wallets/create-vault) | `createVaultWithApproval()` |
| Create a contact | [Create Contact](/accounts-and-wallets/address-book/create-contact) | `createContactWithApproval()` |
| Update a contact | [Update Contact](/accounts-and-wallets/address-book/update-contact) | `updateContactWithApproval()` |
| Create a bank account | [Create Bank Account](/accounts-and-wallets/address-book/create-bank-account) | `createBankAccountWithApproval()` |

### Transactions

A new transaction comes back with `status: "PENDING"`. If your policy approves on creation, it comes back in a later status and needs no action.

| Flow | Create endpoint | SDK |
| - | - | - |
| Transfer | [Create Transfer](/transactions/create-transfer) | `createTransactionWithApproval()` creates and approves. `createTransferTransaction()` only creates. |
| Contract call | [Create Contract Call](/transactions/create-contract-call) | Call `approveChangeRequest()` after create. |
| Stake | [Stake Resource](/transactions/stake-resource) | Call `approveChangeRequest()` after create. |
| Delegate | [Delegate Resource](/transactions/delegate-resource) | Call `approveChangeRequest()` after create. |
| Replace | [Replace Transaction](/transactions/replace-transaction) | Call `approveChangeRequest()` after create. |
| Ramp | [Execute a Ramp Quote](/transactions/ramps/execute-quote) | `createTransactionFromIntent()` approves for you. |
| FX | [Execute an FX Quote](/transactions/fx/execute-quote) | `createTransactionFromIntent()` approves for you. |
| Trade | [Execute a Trade Quote](/transactions/trade/execute-quote) | `createTransactionFromIntent()` approves for you. |

## Approval flow

<Steps>
  <Step title="Create or update the entity">
    Call the endpoint from [What needs approval](#what-needs-approval) and keep the `id` from the response.
  </Step>

  <Step title="Get the approval message">
    Call [Get Approval Message](/approvals/get-approval-message) with `entityId` set to that `id`. Save the `approvalId` and `message`.
  </Step>

  <Step title="Sign the message">
    Sign the exact `message` with your API user's private key, the same key that signs your requests (ECDSA with SHA-256), and hex-encode the signature.
  </Step>

  <Step title="Submit the action">
    Call [Submit Approval Action](/approvals/submit-approval-action) with the `approvalId`, `action: "approve"` (or `"reject"`), and the signature.
  </Step>

  <Step title="Confirm the result">
    Fetch the entity. Track a transaction with [Retrieve a Transaction](/transactions/retrieve-transaction) or [webhooks](/api-basics/webhooks) until it reaches `COMPLETED`, `FAILED`, or `DECLINED`. Check a vault with [Retrieve a Vault](/accounts-and-wallets/retrieve-vault). Check that a contact or bank account `status` moved from `PENDING` to `APPROVED` with [Retrieve Contact](/accounts-and-wallets/address-book/retrieve-contact) or [Retrieve Bank Account](/accounts-and-wallets/address-book/retrieve-bank-account).
  </Step>
</Steps>

## Approve with the SDK

`approveChangeRequest()` gets the approval message, signs it with the client's configured key (a private key or AWS KMS), and submits the action. It works for any `entityId` in the table above. The `...WithApproval()` helpers call it for you.

```typescript theme={null}
// Create and approve in one call
const contact = await apiClient.createContactWithApproval(request);

// Or create first, then approve
const vault = await apiClient.createVault(request);
await apiClient.approveChangeRequest({
  entityId: vault.id,
  action: "approve",
});
const approvedVault = await apiClient.getVaultById(vault.id);
```

<CardGroup cols={2}>
  <Card title="Get Approval Message" icon="envelope-open-text" href="/approvals/get-approval-message">
    The message to sign for a pending change request.
  </Card>

  <Card title="Submit Approval Action" icon="signature" href="/approvals/submit-approval-action">
    Approve or reject with the signed message.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.