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

# Attribution Debugging

> How to trace a click through to its conversions when a partner reports a missing click, a broken pixel, or a disputed payout.

A partner says a click never landed. An advertiser disputes a conversion. A pixel looks like it fired twice. This page is the route through the tools for each of those.

The records themselves — clicks, conversions, transactions, orders — are read through the generic entity tools. Their full response shapes and listing filters are in [Event response fields](/ai-automation/mcp/tools/generic#event-response-fields).

## Start here

| You have                                                            | Use                                                                                                                                                                                                    |
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| A 32-character transaction ID and the whole story to piece together | `get_entity(type="transaction", id=…)` — click, conversions, pixel fires, and holds in one call                                                                                                        |
| A transaction ID and only the click matters                         | `get_entity(type="click", id=…)`                                                                                                                                                                       |
| A conversion ID                                                     | `get_entity(type="conversion", id=…)`                                                                                                                                                                  |
| A store order id, and you need the store behind it                  | `get_entity(type="order", id=…)`                                                                                                                                                                       |
| No ID — a time window and some filters                              | [`search_activity`](/ai-automation/mcp/tools/reporting#search_activity) for a raw stream, or [`list_entities`](/ai-automation/mcp/tools/generic#list_entities) for filtered, cursor-paginated listings |
| A count or a breakdown, not individual records                      | [`run_performance_report`](/ai-automation/mcp/tools/reporting#run_performance_report)                                                                                                                  |

Clicks and transactions are identified by the **32-character transaction ID**; conversions by the **conversion ID**.

## Trace one transaction end to end

`get_entity(type="transaction", …)` is the fastest path from an ID to an answer, because it returns every layer of the chain at once:

```text theme={null}
get_entity(type="transaction", id="a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6")
```

| Layer                 | What it tells you                                                                                 |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| `click`               | Did the click land at all, and cleanly? A non-zero `error_code` names the reason it was rejected  |
| `conversions`         | What fired, when, for how much, and under which attribution method                                |
| `pixels`              | Whether the partner's pixel actually fired — `is_success` plus `debug_information` when it didn't |
| `on_hold_conversions` | Whether a conversion exists but is waiting out a holding period rather than missing               |

Each collection is capped at 10 items. Compare `<name>_total` with `<name>_returned` to spot truncation; when conversions are truncated, `conversions_note` hands you the exact `list_entities` call to page through the rest.

## Error codes worth knowing

Every click and conversion carries an `error_code`. `0` means accepted — it has no lookup row, so `get_entity(type="click_error_code", id=0)` returns `INVALID_ARGUMENT`. For any non-zero code, resolve it with `get_entity(type="click_error_code", id=<code>)` or `get_entity(type="conversion_error_code", id=<code>)`. These are the ones you'll meet most:

| Click code | Meaning                                           |
| ---------- | ------------------------------------------------- |
| `0`        | Accepted — no error                               |
| `1`        | Offer expired                                     |
| `2`        | Cap reached (click or conversion cap hit)         |
| `9`        | Geo targeting mismatch                            |
| `28`       | SmartSwitch blocked — no eligible offer available |
| `1016`     | Fraud detected (Forensiq / fraud threshold)       |

| Conversion code | Meaning                                                       |
| --------------- | ------------------------------------------------------------- |
| `4`             | Cap exceeded (offer conversion or revenue cap hit)            |
| `5`             | Outside the lookback window — the click is older than 90 days |
| `8`             | Duplicate conversion — that transaction ID already converted  |
| `12`            | Invalid or missing transaction ID                             |
| `13`            | Click not found — the transaction ID isn't in the system      |
| `14`            | Click and conversion offer mismatch                           |
| `22`            | Advertiser flagged as fraudulent                              |

For a breakdown by code rather than one record at a time, group a report on it: `run_performance_report(dimensions="click_error_code")` or `conversion_error_code`.

## Common investigations

**"My click never registered."** Fetch the click. A non-zero `error_code` is the answer — resolve the number to its meaning with `get_entity(type="click_error_code", id=<code>)`. Code `0` means accepted, and has no lookup row. If the click isn't found at all, widen to `search_activity(type="click")` over the window with the partner's `affiliate_id` and `sub1` to confirm whether anything arrived.

**"This conversion shouldn't have paid out."** Fetch the conversion and check `attribution_method`, `click_timestamp` against `timestamp`, and `is_scrub`. Then fetch the offer's `session_duration` with [`get_offer`](/ai-automation/mcp/tools/offers-affiliates#get_offer) to confirm the click was inside the attribution window.

**"The numbers don't match the invoice."** Check `list_entities(type="reporting_adjustment", filters={"from":…, "to":…})` first. Manual adjustments are applied on top of tracked data and are the usual explanation for a gap between a report and a bill.

**"A conversion is missing from my report."** Look for it on hold: `list_entities(type="on_hold_conversion", filters={"affiliate_id": …})`. Held conversions don't count until the holding period ends.

**"Which store did this order come from?"** `get_entity(type="order", id=<store order id>)` returns `shopify_store_url`, `integration_id`, and the `transaction_id` that links it back to the attribution chain.

## Two things that will bite you

<Warning>
  **Identity fields are masked.** `session_user_ip` and `conversion_user_ip` are abbreviated for conversions from GDPR countries; `idfa`, `google_ad_id` and `android_id` have trailing characters replaced; `email` is obfuscated (`a*******@example.com`). This matches the REST conversion export. Treat all of them as personal data.
</Warning>

**Single-record lookups return slightly more than stream searches.** `get_entity` resolves a few values that would be an N+1 across a 1,000-row stream: on clicks that's `offer_name`, `affiliate_name`, `advertiser_name` and `has_conversion`; on conversions it's `error_message` and `campaign_id`. Everything else is identical. If a field you expect is missing from a `search_activity` result, fetch the single record before concluding the data doesn't exist.

<Note>
  The former `get_click` and `get_conversion` tools remain callable for backward compatibility but are deprecated and no longer listed — see [Deprecated tools](/ai-automation/mcp/tools#deprecated-tools).
</Note>

<CardGroup cols={2}>
  <Card title="Event response fields" icon="list" href="/ai-automation/mcp/tools/generic#event-response-fields">
    Every field on a click, conversion, transaction, and order, plus their listing filters.
  </Card>

  <Card title="Agentic Examples" icon="wand-magic-sparkles" href="/ai-automation/mcp/examples">
    Full agent traces, including diagnosing a blocked click end to end.
  </Card>
</CardGroup>
