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

# Making a Payout

> Execute compliant payouts and handle compliance errors

The [Transfer Token API](/api-reference/wallets/transfer-token) enables you to trigger payouts from your treasury wallet to user wallets. The API automatically performs compliance checks and will return specific errors if the recipient has not provided the appropriate information or did not pass the necessary compliance checks.

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
      --url 'https://staging.crossmint.com/api/2025-06-09/wallets/<your-treasury-wallet-locator>/tokens/base-sepolia:usdc/transfers' \
      --header 'X-API-KEY: <your-server-api-key>' \
      --header 'Content-Type: application/json' \
      --data '{
          "recipient": "<recipient-wallet-address>",
          "amount": "100"
      }'
  ```

  ```typescript Node.js theme={null}
  import { CrossmintWallets, createCrossmint } from "@crossmint/wallets-sdk";

  const crossmint = createCrossmint({
      apiKey: "<your-server-api-key>",
  });

  const crossmintWallets = CrossmintWallets.from(crossmint);

  const treasuryLocator = "<your-treasury-wallet-locator>";

  const treasuryWallet = await crossmintWallets.getWallet(treasuryLocator, {
      chain: "base-sepolia",
  });

  await treasuryWallet.useSigner({ type: "server", secret: process.env.WALLET_SIGNER_SECRET! });

  try {
      const { hash, explorerLink } = await treasuryWallet.send(
          "<recipient-wallet-address>",
          "usdc",
          "100",
          { transactionType: "regulated-transfer" }
      );

      console.log(`Transfer successful: ${hash}`);
      console.log(`Explorer: ${explorerLink}`);
  } catch (error) {
      console.error("Transfer failed:", error.message);
      // Handle compliance errors - see error codes below
  }
  ```

  ```python Python theme={null}
  import requests

  treasury_locator = "<your-treasury-wallet-locator>"
  token_locator = "base-sepolia:usdc"

  url = f"https://staging.crossmint.com/api/2025-06-09/wallets/{treasury_locator}/tokens/{token_locator}/transfers"

  payload = {
      "recipient": "<recipient-wallet-address>",
      "amount": "100"
  }
  headers = {
      "X-API-KEY": "<your-server-api-key>",
      "Content-Type": "application/json"
  }

  response = requests.post(url, json=payload, headers=headers)

  print(response.json())
  ```
</CodeGroup>

<Note>
  **Signing transactions (REST API):** The cURL and Python examples above use the simplified [Transfer Token](/api-reference/wallets/transfer-token) endpoint. If your integration requires custom transaction signing, see the full create → sign → approve flow in [Send a Transaction (EVM) — REST tab](/wallets/guides/send-transaction-evm#rest).
</Note>

Wallet locator options for a treasury wallet:

* `<walletAddress>` (e.g., `0x1234...5678`)
* `chainType[:<walletType>]:alias:<alias>` (e.g., `evm:smart:alias:treasury`)

<Warning>
  Transfers are irreversible once executed. Clients must ensure that all transaction details are correct before submitting a transfer request.
</Warning>

## Compliance Errors

If a payout fails compliance checks, the API will return an error with a specific reason code. Here are the potential compliance-related errors:

<AccordionGroup>
  <Accordion title="recipient_personal_data_missing" icon="user-xmark">
    **Error Message:** "Required personal data is missing to complete regulated transfer"

    **Description:** The recipient wallet has not provided all personal data required for compliance screening. The recipient must complete their profile with first name, last name, date of birth, and country of residence.

    **Resolution:** Ensure the recipient has attached their personal data using the [user onboarding API](/identity/register-user-data#step-2-register-user-data).

    <Expandable title="How to test">
      In staging, send a transfer to any user wallet that has not had [personal data registered](/identity/register-user-data#step-2-register-user-data).
    </Expandable>

    ```jsonc theme={null}
    // Example error response
    {
        "error": {
            "reason": "recipient_personal_data_missing",
            "message": "Required personal data is missing to complete regulated transfer"
        }
    }
    ```
  </Accordion>

  <Accordion title="recipient_wallet_sanctioned" icon="shield-xmark">
    **Error Message:** "Recipient wallet address is sanctioned and can't receive assets"

    **Description:** The recipient's wallet address failed Elliptic sanctions screening. This indicates the address has been flagged in sanctions lists or is associated with prohibited activities.

    **Resolution:** The payout cannot proceed. The recipient's wallet address has been identified as high-risk and is blocked from receiving payouts.

    <Expandable title="How to test">
      In staging, you can trigger a sanctions error by using the following special addresses across different chains as the recipient:

      * EVM: `0xc9b888e8f2c9c60f72f84e97e4416c3aca3e1f7c`
      * Solana: `7H7Dph61J9W9WzvRUQbM1tsPJpEQhaQ3GVxPSj1EnSuw`
      * Stellar: `G5CLUPQPRWQXKHASBYSYMIPHE2ZMIFLMEH3ROBTOQMR24YWQIFQW2RY5`
    </Expandable>

    ```jsonc theme={null}
    // Example error response
    {
        "error": {
            "reason": "recipient_wallet_sanctioned",
            "message": "Recipient wallet address is sanctioned and can't receive assets"
        }
    }
    ```
  </Accordion>

  <Accordion title="recipient_person_sanctioned" icon="user-shield">
    **Error Message:** "Recipient user is sanctioned and can't receive assets"

    **Description:** The recipient's personal information failed sanctions and PEP (Politically Exposed Person) screening. This indicates the individual is on a sanctions list or is a politically exposed person subject to enhanced due diligence.

    **Resolution:** The payout cannot proceed. The recipient has been identified as high-risk based on their personal information and is blocked from receiving payouts.

    <Expandable title="How to test">
      In staging, if you create a user profile with the name "Sanctioned User Name", Crossmint will consider them sanctioned. You can use this for testing.

      To trigger this error, [create a user](/identity/register-user-data#step-2-register-user-data) with the following data:

      ```json theme={null}
      {
          "personalData": {
              "firstName": "Sanctioned User Name",
              // ... any value for other required fields
          }
      }
      ```

      Then attempt a payout to that user's wallet.
    </Expandable>

    ```jsonc theme={null}
    // Example error response
    {
        "error": {
            "reason": "recipient_person_sanctioned",
            "message": "Recipient user is sanctioned and can't receive assets"
        }
    }
    ```
  </Accordion>

  <Accordion title="recipient_type_unsupported" icon="circle-xmark">
    **Error Message:** "Currently, regulated transfers can only be sent to Crossmint-managed wallets."

    **Description:** The destination address is an external wallet, not a Crossmint-managed wallet. Payouts currently only support transfers between Crossmint treasury wallets and Crossmint user wallets.

    **Resolution:** Ensure the recipient has a Crossmint wallet. External wallet addresses are not supported for payouts.

    <Info>
      External wallet recipients are not currently supported. Contact [support](https://www.crossmint.com/contact/sales) for more information.
    </Info>

    ```jsonc theme={null}
    // Example error response
    {
        "error": {
            "reason": "recipient_type_unsupported",
            "message": "Currently, regulated transfers can only be sent to Crossmint-managed wallets."
        }
    }
    ```
  </Accordion>
</AccordionGroup>

## Error Handling Best Practices

When implementing payouts, follow these best practices for error handling:

<Steps>
  <Step title="Validate recipient before transfer">
    Before initiating a payout, verify that the recipient has completed their onboarding and provided all required personal data. This can help prevent `recipient_personal_data_missing` errors.
  </Step>

  <Step title="Implement retry logic for transient errors">
    Some errors may be transient (e.g., temporary API issues). Implement appropriate retry logic with exponential backoff for non-compliance errors.
  </Step>

  <Step title="Log compliance failures">
    Log all compliance-related errors for audit purposes. These logs are important for regulatory reporting and investigating failed transfers.
  </Step>

  <Step title="Notify users of compliance issues">
    When a payout fails due to compliance issues, notify the affected users with clear instructions on how to resolve the issue (e.g., completing their profile, contacting support).
  </Step>
</Steps>

## Supported Transfer Types

<Note>
  Compliant payouts currently work for transfers between **Crossmint treasury wallets** and **Crossmint user wallets**. Payouts to external wallets are not supported.
</Note>

## Additional Resources

<CardGroup cols={2}>
  <Card title="API Reference" icon="terminal" color="#B56710" href="/api-reference/wallets/transfer-token">
    Deep dive into the transfer API reference
  </Card>

  <Card title="Talk to an expert" icon="message" iconType="duotone" color="#ADD8E6" href="https://www.crossmint.com/contact/sales">
    Contact the Crossmint sales team for support
  </Card>
</CardGroup>
