> ## 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.

# Submit an Approval Action

> Approve or reject a change request waiting for approval (a transaction, vault, contact, or bank account) with a signed approval message.

**POST** `/api/external/change_requests/approvals/{approvalId}/action/`

Send the signed approval message from [Get Approval Message](/approvals/get-approval-message) to approve or reject. See [Approvals](/approvals/overview) for the full flow.

## Path parameter

<ParamField path="approvalId" type="string" required>
  The `approvalId` returned by [Get Approval Message](/approvals/get-approval-message).
</ParamField>

## Request body

<ParamField body="action" type="ApprovalAction" required>
  `approve` or `reject`. See [ApprovalAction](/api-basics/data-models#approvalaction).
</ParamField>

<ParamField body="signature" type="string" required>
  Hex-encoded ECDSA (SHA-256) signature of the approval `message`, made with your API user's private key.
</ParamField>

<ParamField body="reason" type="string">
  Note recorded with the action. The SDK sends `ok` unless you pass another value.
</ParamField>

## Response

Returns an [ApprovalActionResponse](/api-basics/data-models#approvalactionresponse).

<ResponseField name="success" type="boolean">
  Whether PrimeVault accepted the action.
</ResponseField>

<ResponseField name="status" type="string">
  Approval status after the action.
</ResponseField>

<ResponseField name="id" type="string">
  ID of the approval record.
</ResponseField>

<ResponseField name="entityId" type="string">
  ID of the transaction, vault, contact, or bank account the action applied to.
</ResponseField>

<Note>
  After you approve, fetch the entity to confirm its state:

  * **Transaction:** [Retrieve a Transaction](/transactions/retrieve-transaction) or [webhooks](/api-basics/webhooks) until it reaches `COMPLETED`, `FAILED`, or `DECLINED`.
  * **Vault:** [Retrieve a Vault](/accounts-and-wallets/retrieve-vault).
  * **Contact:** [Retrieve a Contact](/accounts-and-wallets/address-book/retrieve-contact). Status moves from `PENDING` to `APPROVED` or `DECLINED`.
  * **Bank account:** [Retrieve a Bank Account](/accounts-and-wallets/address-book/retrieve-bank-account). Status moves from `PENDING` to `APPROVED` or `DECLINED`.
</Note>

<RequestExample dropdown>
  ```json Request example theme={null}
  {
    "path": {
      "approvalId": "approval_123"
    },
    "body": {
      "action": "approve",
      "signature": "<hex-encoded signature of message>",
      "reason": "ok"
    }
  }
  ```

  ```bash cURL theme={null}
  # Sample only. Generate a new signed token for each request
  # (see Authentication). Tokens expire after 120 seconds.
  curl --request POST \
    --url "https://api.primevault.com/api/external/change_requests/approvals/approval_123/action/" \
    --header "Authorization: Bearer <signed JWT>" \
    --header "Api-Key: <API key>" \
    --header "Content-Type: application/json" \
    --data '{
      "action": "approve",
      "signature": "<hex-encoded signature of message>",
      "reason": "ok"
    }'
  ```

  ```typescript JavaScript SDK theme={null}
  // Sign the message yourself and submit it:
  const result = await apiClient.submitChangeApprovalAction(
    approvalMessage.approvalId,
    "approve",
    signatureHex,
  );

  // Or fetch, sign, and submit in one call.
  // entityId is a transaction, vault, contact, or bank account ID.
  await apiClient.approveChangeRequest({
    entityId: transaction.id,
    action: "approve",
  });
  ```
</RequestExample>

<ResponseExample>
  ```json JSON example theme={null}
  {
    "success": true,
    "entityId": "transaction_123"
  }
  ```
</ResponseExample>


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