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

# Verify Attribution

> Confirm that a transaction carries valid Turtle tracking data for your distributor

<Note>
  Requires an API key via the `X-API-Key` header. See [API Keys](/sdk/authentication/api-keys). {/* VERIFY: canonical auth header, consistent with the deposit page. KB earn-api.md records both `X-API-Key` and `Authorization: Bearer` as accepted. */}
</Note>

## Overview

`GET /v2/actions/verify`

Check whether a transaction carries valid Turtle tracking data. Pass a transaction hash and chain ID, and the endpoint returns the tracking tag, the parsed attribution `metadata` (including `distributorId`, `opportunityId`, the deposited `amount`, and `referralCode`), and whether the signature is from Turtle's attribution wallet. Use it to confirm attribution independently, or for debugging.

This works for any attributed deposit, however it was generated. A deposit built through [Deposit](/sdk/earn/deposit) and a no-code [share-link](/partner-products/share-links) deposit both embed the same tracking signature, so both verify the same way.

<CodeGroup>
  ```bash curl theme={null}
  curl -X GET "https://earn.turtle.xyz/v2/actions/verify?chainId=1&txHash=0xedfdf71e..." \
    -H "X-API-Key: pk_live_xxxxx"
  ```

  ```typescript TypeScript theme={null}
  const params = new URLSearchParams({
    chainId: '1',
    txHash: '0xedfdf71e0e4daec5afcb87988821a8bccd5c282647c8e81a65a71181a44a8e51',
  });

  const response = await fetch(
    `https://earn.turtle.xyz/v2/actions/verify?${params}`,
    { headers: { 'X-API-Key': 'pk_live_xxxxx' } }
  );
  const data = await response.json();
  ```
</CodeGroup>

**Query Parameters**

<ParamField query="chainId" type="integer" required>
  The chain ID where the transaction was executed (e.g., `1` for Ethereum, `42161` for Arbitrum).
</ParamField>

<ParamField query="txHash" type="string" required>
  The transaction hash to verify (`0x` followed by 64 hex characters).
</ParamField>

**Response**

```json theme={null}
{
  "tag": "turtle:v1:dist123:ref456",
  "metadata": {
    "action": "deposit",
    "actionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "amount": "1000000",
    "amountUsd": "1.00",
    "distributorId": "dist123",
    "opportunityId": "550e8400-e29b-41d4-a716-446655440000",
    "referralCode": "ref456",
    "tokenIn": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "tokenInDecimals": 6
  },
  "signatureValid": true
}
```

<ResponseField name="tag" type="string">
  The raw tracking tag found in the transaction data.
</ResponseField>

<ResponseField name="metadata" type="object">
  Parsed attribution metadata for the transaction.

  <Expandable title="metadata">
    <ResponseField name="action" type="string">
      The attributed action type (e.g., `deposit`).
    </ResponseField>

    <ResponseField name="actionId" type="string">
      The action ID associated with the attributed transaction.
    </ResponseField>

    <ResponseField name="amount" type="string">
      The deposited amount in the input token's smallest unit.
    </ResponseField>

    <ResponseField name="amountUsd" type="string">
      The deposited amount in USD.
    </ResponseField>

    <ResponseField name="distributorId" type="string">
      The distributor the transaction is attributed to.
    </ResponseField>

    <ResponseField name="opportunityId" type="string">
      The opportunity the deposit was made into.
    </ResponseField>

    <ResponseField name="referralCode" type="string">
      The referral code embedded in the tracking data, if present.
    </ResponseField>

    <ResponseField name="tokenIn" type="string">
      The address of the input token.
    </ResponseField>

    <ResponseField name="tokenInDecimals" type="integer">
      The decimals of the input token.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="signatureValid" type="boolean" required>
  Whether the tracking signature is from Turtle's attribution wallet.
</ResponseField>

<ResponseField name="error" type="string">
  Error message if verification failed (e.g., no tracking data found).
</ResponseField>

## Error Handling

<AccordionGroup>
  <Accordion title="Malformed txHash or chainId">
    **Status:** 400 Bad Request

    ```json theme={null}
    {
      "error": "invalid_request",
      "message": "Invalid txHash or chainId"
    }
    ```

    **Solution:** Pass a `chainId` integer for a supported chain and a `txHash` of `0x` followed by 64 hex characters.
  </Accordion>

  <Accordion title="No tracking data found">
    **Status:** 404 Not Found

    ```json theme={null}
    {
      "error": "tracking_data_not_found",
      "message": "No tracking data found in transaction"
    }
    ```

    **Solution:** Confirm the transaction is the attributed deposit and that it embedded a Turtle tracking signature. A plain transfer or a deposit built without a `distributorId` carries no tracking data.
  </Accordion>

  <Accordion title="Invalid signature">
    **Status:** 200 OK

    ```json theme={null}
    {
      "tag": "turtle:v1:dist123:ref456",
      "metadata": {
        "action": "deposit",
        "actionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "amount": "1000000",
        "amountUsd": "1.00",
        "distributorId": "dist123",
        "opportunityId": "550e8400-e29b-41d4-a716-446655440000",
        "referralCode": "ref456",
        "tokenIn": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
        "tokenInDecimals": 6
      },
      "signatureValid": false
    }
    ```

    **Solution:** A tracking tag is present but its signature is not from Turtle's attribution wallet, so the deposit is not attributed. Rebuild the deposit through [Deposit](/sdk/earn/deposit) so the tracking signature is generated by Turtle.
  </Accordion>
</AccordionGroup>

## Related

* [Deposit](/sdk/earn/deposit): Generate the deposit whose attribution you are verifying
* [Distributor Activity](/sdk/earn-api/deposits): List every deposit attributed to your distributor
* [Distributor Model](/sdk/concepts/distributor-model): How attribution and revenue tracking work
