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

# Confirm Claim Transaction

> POST /claims/confirm - Submit signed claim transaction to complete token claim

## Overview

Receives a user-signed claim transaction from `/claims/mint`, adds the protocol's mint authority signature, and submits the complete transaction to the Solana blockchain to finalize the token claim.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.zcombinator.io/claims/confirm \
    -H "Content-Type: application/json" \
    -d '{
      "signedTransaction": "4MzR7dxJNJRVP1Q6k7Y3j8X...",
      "transactionKey": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM_1642248400000"
    }'
  ```

  ```javascript fetch theme={null}
  const response = await fetch('https://api.zcombinator.io/claims/confirm', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      signedTransaction: signedTransactionBase58,
      transactionKey: result.transactionKey
    })
  });

  const confirmResult = await response.json();
  ```

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

  data = {
      "signedTransaction": signed_transaction_base58,
      "transactionKey": result["transactionKey"]
  }

  response = requests.post(
      'https://api.zcombinator.io/claims/confirm',
      json=data,
      headers={'Content-Type': 'application/json'}
  )

  result = response.json()
  ```
</CodeGroup>

## Request Parameters

<ParamField body="signedTransaction" type="string" required>
  Base58 encoded transaction signed by the user's wallet
</ParamField>

<ParamField body="transactionKey" type="string" required>
  Unique transaction identifier returned from `/claims/mint`
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  Indicates if the operation was successful
</ResponseField>

<ResponseField name="transactionSignature" type="string">
  The Solana transaction signature/hash
</ResponseField>

<ResponseField name="tokenAddress" type="string">
  The token address that was claimed from
</ResponseField>

<ResponseField name="claimAmount" type="string">
  The amount of tokens that were successfully claimed
</ResponseField>

<ResponseField name="splitRecipients" type="array">
  Array of recipients who received tokens from this claim, each containing:

  * `wallet` (string): The recipient's wallet address
  * `amount` (string): The amount allocated to this recipient
  * `label` (string, optional): Description of the recipient (e.g., "Developer")
</ResponseField>

<ResponseField name="confirmation" type="object">
  Blockchain confirmation details
</ResponseField>

### Success Response

```json theme={null}
{
  "success": true,
  "transactionSignature": "5VfYiDvQMBSWxKJLa9NLPQ1x3...",
  "tokenAddress": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "claimAmount": "1000000",
  "splitRecipients": [
    {
      "wallet": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
      "amount": "900000",
      "label": "Developer"
    }
  ],
  "confirmation": {
    "value": {
      "err": null
    },
    "context": {
      "slot": 123456789
    }
  }
}
```

## Error Responses

<AccordionGroup>
  <Accordion title="400 - Missing Parameters">
    ```json theme={null}
    {
      "error": "Missing required fields: signedTransaction and transactionKey"
    }
    ```
  </Accordion>

  <Accordion title="400 - Transaction Data Not Found">
    ```json theme={null}
    {
      "error": "Transaction data not found. Please call /claims/mint first."
    }
    ```

    This occurs when:

    * Invalid or expired `transactionKey`
    * Temporary storage was cleared
    * Transaction was already processed
  </Accordion>

  <Accordion title="400 - Eligibility Changed">
    ```json theme={null}
    {
      "error": "Claim eligibility has changed. Requested amount exceeds available claim amount."
    }
    ```

    Eligibility was re-validated and the user no longer has enough tokens available.
  </Accordion>

  <Accordion title="400 - No Tokens Available">
    ```json theme={null}
    {
      "error": "No tokens available to claim anymore"
    }
    ```
  </Accordion>

  <Accordion title="500 - Configuration Error">
    ```json theme={null}
    {
      "error": "Server configuration error"
    }
    ```

    Required environment variables (RPC\_URL, PROTOCOL\_PRIVATE\_KEY) are missing.
  </Accordion>

  <Accordion title="500 - Transaction Failed">
    ```json theme={null}
    {
      "error": "Failed to confirm claim"
    }
    ```

    This can occur due to:

    * Network congestion
    * Insufficient funds for transaction fees
    * Invalid transaction signature
    * Blockchain errors
  </Accordion>
</AccordionGroup>

## Process Flow

This endpoint completes the two-phase claim process:

<Steps>
  <Step title="Validate Parameters">
    Ensures both required fields are provided
  </Step>

  <Step title="Retrieve Transaction Data">
    Fetches stored transaction details using the `transactionKey`
  </Step>

  <Step title="Re-validate Eligibility">
    Performs a security check to ensure claim eligibility hasn't changed
  </Step>

  <Step title="Deserialize Transaction">
    Converts the Base58 signed transaction back to a Solana Transaction object
  </Step>

  <Step title="Add Protocol Signature">
    Signs the transaction with the protocol's keypair (mint authority)
  </Step>

  <Step title="Submit to Blockchain">
    Sends the fully signed transaction to the Solana network
  </Step>

  <Step title="Wait for Confirmation">
    Monitors the transaction until it's confirmed on-chain
  </Step>

  <Step title="Cleanup">
    Removes the temporary transaction data
  </Step>
</Steps>

## Security Re-validation

<Warning>
  **Important Security Check**: The API re-validates claim eligibility before processing to prevent race conditions where:

  * Other users claimed tokens in the meantime
  * Inflation periods advanced
  * User's eligibility changed for any reason
</Warning>

This prevents users from claiming more than they're entitled to, even if they hold onto signed transactions.

## Rate Limiting

This endpoint is subject to rate limiting:

* **8 requests per IP** per 2-minute window
* Returns HTTP 429 when limit exceeded

## Transaction Lifecycle

The claim transaction follows this lifecycle:

1. **Creation**: `/claims/mint` creates unsigned transaction
2. **Storage**: Transaction data stored temporarily (10min max)
3. **Signing**: User signs transaction with their wallet
4. **Confirmation**: This endpoint adds protocol signature and submits
5. **Cleanup**: Transaction data removed
6. **Finality**: Tokens are permanently transferred to user

## Transaction Data Cleanup

<Info>
  **Cleanup Policy**:

  * Successful transactions: Immediately cleaned up
  * Failed transactions: Remain until expiration
  * Expired transactions: Automatically removed after 10 minutes
</Info>

## After Successful Claim

Once tokens are successfully claimed:

1. **Verify Balance**: Check user's token account balance
2. **Update UI**: Refresh claim eligibility for next period
3. **Transaction Proof**: Use `transactionSignature` for verification

## Transaction Signature

The returned `transactionSignature` can be used to:

* View the transaction on Solana explorers
* Verify the token claim on-chain
* Provide proof of claim to users
* Track transaction status

Example Solana Explorer URL:

```
https://explorer.solana.com/tx/${transactionSignature}
```

## Integration Notes

<Tip>
  **Best Practice**: Always handle both success and error cases gracefully. Failed claims may be retryable if the issue was network-related rather than eligibility-related.
</Tip>

<Note>
  **Multi-instance Deployments**: If running multiple API instances, consider using Redis or similar for shared transaction state instead of in-memory storage.
</Note>
