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

# Paying out Bitcoin rewards

> Send Bitcoin rewards to customers using the Grid API

This guide covers how to distribute Bitcoin rewards to your customers, including quote creation, execution options, and tracking delivery.

## Overview

Distributing Bitcoin rewards involves creating a quote that converts your fiat balance (typically USD) to Bitcoin and sends it to the customer's wallet. You have flexibility in how you lock amounts, register destinations, and execute transfers.

## Basic Flow

1. **Create a quote** - Specify source account, destination, and amount
2. **Execute the quote** - Either immediately or after review
3. **Monitor completion** - Track via webhooks

## Finding your platform's internal account

In this guide, we'll use the platform's USD internal account as the funding source for the rewards.
You can find your platform's internal account by listing all internal accounts for your platform.

```bash theme={null}
curl -X GET "https://api.lightspark.com/grid/2025-10-13/platform/internal-accounts" \
  -H "Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET"
```

Response:

```json theme={null}
{
  "data": [
    {
      "id": "InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965",
      "balance": {
        "amount": 10000,
        "currency": {
          "code": "USD",
          "name": "United States Dollar",
          "symbol": "$",
          "decimals": 2
        }
      },
      "fundingPaymentInstructions": [...],
      "createdAt": "2025-10-03T12:00:00Z",
      "updatedAt": "2025-10-03T12:00:00Z"
    }
  ]
}
```

## Creating a Quote

The core request specifies your platform's internal account as the source and the customer's wallet as the destination.

First, create an external account for the destination wallet:

```bash theme={null}
curl -X POST "https://api.lightspark.com/grid/2025-10-13/customers/external-accounts" \
  -H "Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
    "currency": "BTC",
    "accountInfo": {
      "accountType": "SPARK_WALLET",
      "address": "spark1pgssyuuuhnrrdjswal5c3s3rafw9w3y5dd4cjy3duxlf7hjzkp0rqx6dj6mrhu"
    }
  }'
```

Then create the quote using the external account ID:

```bash theme={null}
curl -X POST "https://api.lightspark.com/grid/2025-10-13/quotes" \
  -H "Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "source": {
      "sourceType": "ACCOUNT",
      "accountId": "InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965"
    },
    "destination": {
      "destinationType": "ACCOUNT",
      "accountId": "ExternalAccount:b23dcbd6-dced-4ec4-b756-3c3a9ea3d456"
    },
    "lockedCurrencySide": "SENDING",
    "lockedCurrencyAmount": 100,
    "immediatelyExecute": true,
    "description": "Weekly reward payout"
  }'
```

Response:

```json theme={null}
{
  "id": "Quote:019542f5-b3e7-1d02-0000-000000000020",
  "status": "PROCESSING",
  "createdAt": "2025-10-03T15:00:00Z",
  "expiresAt": "2025-10-03T15:05:00Z",
  "source": {
    "sourceType": "ACCOUNT",
    "accountId": "InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965"
  },
  "destination": {
    "destinationType": "ACCOUNT",
    "accountId": "ExternalAccount:b23dcbd6-dced-4ec4-b756-3c3a9ea3d456"
  },
  "sendingCurrency": {
    "code": "USD",
    "decimals": 2
  },
  "receivingCurrency": {
    "code": "BTC",
    "decimals": 8
  },
  "totalSendingAmount": 100,
  "totalReceivingAmount": 810,
  "exchangeRate": 8.1,
  "feesIncluded": 5,
  "transactionId": "Transaction:019542f5-b3e7-1d02-0000-000000000025"
}
```

## Locking Amount: Sending vs. Receiving

When creating a quote, you can choose to either lock the amount you're sending (fiat) or the amount the customer receives (Bitcoin).

### Lock Sending Amount

Use this when you want to send a fixed dollar amount (e.g., \$1.00 reward).

```json theme={null}
{
  "lockedCurrencySide": "SENDING",
  "lockedCurrencyAmount": 100 // $1.00 in cents
}
```

The customer receives whatever Bitcoin this amount buys at the current rate.

### Lock Receiving Amount

Use this when you want the receiver to receive a specific Bitcoin amount (e.g., 1000 sats).

```json theme={null}
{
  "lockedCurrencySide": "RECEIVING",
  "lockedCurrencyAmount": 1000 // 1000 satoshis
}
```

Your platform account is debited whatever fiat amount is needed to send that Bitcoin amount.

<Tip>
  For consistent dollar-value rewards, use `SENDING`. For consistent
  Bitcoin-value rewards, use `RECEIVING`.
</Tip>

## Execution Options

### Immediate Execution (Market Order)

Set `immediatelyExecute: true` to create and execute the quote in one step. This is ideal for automated reward distribution where you accept the current market rate.

```json theme={null}
{
  "immediatelyExecute": true
}
```

The quote is created and executed immediately. You receive a `transactionId` in the response.

### Two-Step Execution (Review Before Sending)

Omit `immediatelyExecute` or set it to `false` to review the quote before executing.

```json theme={null}
{
  "immediatelyExecute": false // or omit this field
}
```

The response will be the same as the immediate execution response, but the status will be `PENDING` and you'll have until the quote's `expiresAt` timestamp to execute the quote.

After reviewing the quote's exchange rate and fees, execute it:

```bash theme={null}
curl -X POST "https://api.lightspark.com/grid/2025-10-13/quotes/{quoteId}/execute" \
  -H "Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET"
```

<Note>
  Quotes expire after a short time (typically 5 minutes). You must execute
  before expiration.
</Note>

## Destination Options

### Pre-Registered External Account

Create the external account first, then reference it by ID in the quote.

First, create the external account:

```bash theme={null}
curl -X POST "https://api.lightspark.com/grid/2025-10-13/customers/external-accounts" \
  -H "Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
    "currency": "BTC",
    "accountInfo": {
      "accountType": "SPARK_WALLET",
      "address": "spark1pgssyuuuhnrrdjswal5c3s3rafw9w3y5dd4cjy3duxlf7hjzkp0rqx6dj6mrhu"
    }
  }'
```

Then reference it in `/quotes`:

```json theme={null}
{
  "destination": {
    "accountId": "ExternalAccount:b23dcbd6-dced-4ec4-b756-3c3a9ea3d456"
  }
}
```

<Tip>
  Pre-register external accounts for customers who receive regular rewards. This
  avoids duplicate account creation and improves performance.
</Tip>

## Tracking Delivery

### Webhook Notification

When the Bitcoin transfer completes, you'll receive a webhook:

```json theme={null}
{
  "id": "Webhook:019542f5-b3e7-1d02-0000-000000000030",
  "type": "OUTGOING_PAYMENT.COMPLETED",
  "timestamp": "2025-10-03T15:02:00Z",
  "data": {
    "id": "Transaction:019542f5-b3e7-1d02-0000-000000000025",
    "status": "COMPLETED",
    "type": "OUTGOING",
    "sentAmount": {
      "amount": 100,
      "currency": { "code": "USD" }
    },
    "receivedAmount": {
      "amount": 810,
      "currency": { "code": "BTC" }
    },
    "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
    "settledAt": "2025-10-03T15:01:45Z"
  }
}
```

## Common Patterns

### Fixed Dollar Rewards (e.g., \$1.00 per action)

```json theme={null}
{
  "source": { "sourceType": "ACCOUNT", "accountId": "InternalAccount:..." },
  "destination": { "destinationType": "ACCOUNT", "accountId": "ExternalAccount:..." },
  "lockedCurrencySide": "SENDING",
  "lockedCurrencyAmount": 100,
  "immediatelyExecute": true
}
```

### Fixed Satoshi Rewards (e.g., 1000 sats per action)

```json theme={null}
{
  "source": { "sourceType": "ACCOUNT", "accountId": "InternalAccount:..." },
  "destination": { "destinationType": "ACCOUNT", "accountId": "ExternalAccount:..." },
  "lockedCurrencySide": "RECEIVING",
  "lockedCurrencyAmount": 1000,
  "immediatelyExecute": true
}
```

### Review Before Sending

```json theme={null}
{
  "source": { "sourceType": "ACCOUNT", "accountId": "InternalAccount:..." },
  "destination": { "destinationType": "ACCOUNT", "accountId": "ExternalAccount:..." },
  "lockedCurrencySide": "SENDING",
  "lockedCurrencyAmount": 5000,
  "immediatelyExecute": false
}
```

Then review the exchange rate and fees, and execute:

```bash theme={null}
curl -X POST "https://api.lightspark.com/grid/2025-10-13/quotes/{quoteId}/execute" \
  -H "Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET"
```

## Best Practices

<Check>
  Use `immediatelyExecute: true` for automated, small-dollar rewards where you
  accept market rates.
</Check>

<Check>
  Pre-register external accounts for customers receiving recurring rewards to
  improve performance.
</Check>

<Check>
  Set up webhook handlers to track completion status and update your reward
  records.
</Check>

<Warning>
  Ensure your platform's internal account has sufficient balance before
  distributing rewards. Monitor balances via the `/platform/internal-accounts`
  endpoint or account status webhooks.
</Warning>

## Related Resources

* [Quick Start Guide](/rewards/quickstart) - End-to-end Bitcoin rewards walkthrough
* [Configuring Customers](/rewards/onboarding/configuring-customers) - Customer creation and management
* [API Reference: Quotes](/api-reference/quotes/create-a-transfer-quote) - Complete quote API documentation
* [Handling Webhooks](/rewards/platform-tools/webhooks) - Webhook security and implementation
