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

# Links data

> Learn how to retrieve analytics data on Dub by links, folders, and tags

<Note>
  Analytics endpoints require a [Pro plan](https://dub.co/pricing) subscription
  or higher.
</Note>

Links data allows you to analyze how individual links and link collections are performing across your workspace.

## Link analytics

The top links by event count.

<CodeGroup>
  ```javascript Node.js theme={null}
  import { Dub } from "dub";

  export const dub = new Dub({
    token: process.env.DUB_API_KEY,
  });

  const result = await dub.analytics.retrieve({
    event: "sales",
    groupBy: "top_links",
    interval: "30d",
    // saleType: "new" // Optional: filter by new or recurring sales
  });
  ```

  ```python Python theme={null}
  from dub import Dub

  with Dub(
      token="DUB_API_KEY",
  ) as d_client:
      res = d_client.analytics.retrieve(request={
          "event": "sales",
          "groupBy": "top_links",
          "interval": "30d",
          # "saleType": "new",  # Optional: filter by new or recurring sales
      })
      print(res)
  ```

  ```php PHP theme={null}
  declare(strict_types=1);

  require 'vendor/autoload.php';

  use Dub;
  use Dub\Models\Operations;

  $sdk = Dub\Dub::builder()
      ->setSecurity('DUB_API_KEY')
      ->build();

  $request = new Operations\RetrieveAnalyticsRequest(
      event: 'sales',
      groupBy: 'top_links',
      interval: '30d',
      // saleType: 'new', // Optional: filter by new or recurring sales
  );

  $response = $sdk->analytics->retrieve(
      request: $request
  );

  if ($response->oneOf !== null) {
      // handle response
  }
  ```

  ```go Go theme={null}
  package main

  import(
      "context"
      dubgo "github.com/dubinc/dub-go"
      "github.com/dubinc/dub-go/models/operations"
      "log"
  )

  func main() {
      ctx := context.Background()

      s := dubgo.New(
          dubgo.WithSecurity("DUB_API_KEY"),
      )

      res, err := s.Analytics.Retrieve(ctx, operations.RetrieveAnalyticsRequest{
          Event: dubgo.String("sales"),
          GroupBy: dubgo.String("top_links"),
          Interval: dubgo.String("30d"),
          // SaleType: dubgo.String("new"), // Optional: filter by new or recurring sales
      })
      if err != nil {
          log.Fatal(err)
      }
      if res != nil {
          // handle response
      }
  }
  ```

  ```ruby Ruby theme={null}
  require 'dub'

  s = ::OpenApiSDK::Dub.new(
        security: ::OpenApiSDK::Shared::Security.new(
          token: "DUB_API_KEY",
        ),
      )

  req = ::OpenApiSDK::Operations::RetrieveAnalyticsRequest.new(
    event: "sales",
    groupBy: "top_links",
    interval: "30d",
    # saleType: "new", # Optional: filter by new or recurring sales
  )

  res = s.analytics.retrieve(req)

  if ! res.one_of.nil?
    # handle response
  end
  ```
</CodeGroup>

You can also filter analytics for a specific link (or set of links) by passing the `linkId` parameter. It supports advanced filtering: single value, multiple values (comma-separated), or exclusion (prefix with `-`).

<CodeGroup>
  ```javascript Node.js theme={null}
  import { Dub } from "dub";

  export const dub = new Dub({
    token: process.env.DUB_API_KEY,
  });

  const result = await dub.analytics.retrieve({
    event: "sales",
    groupBy: "top_links",
    linkId: "-fold_xxx...",
    interval: "30d",
    // saleType: "new" // Optional: filter by new or recurring sales
  });
  ```

  ```python Python theme={null}
  from dub import Dub

  with Dub(
      token="DUB_API_KEY",
  ) as d_client:
      res = d_client.analytics.retrieve(request={
          "event": "sales",
          "groupBy": "top_links",
          "linkId": "-fold_xxx...",
          "interval": "30d",
          # "saleType": "new",  # Optional: filter by new or recurring sales
      })
      print(res)
  ```

  ```php PHP theme={null}
  declare(strict_types=1);

  require 'vendor/autoload.php';

  use Dub;
  use Dub\Models\Operations;

  $sdk = Dub\Dub::builder()
      ->setSecurity('DUB_API_KEY')
      ->build();

  $request = new Operations\RetrieveAnalyticsRequest(
      event: 'sales',
      groupBy: 'top_links',
      linkId: '-fold_xxx...',
      interval: '30d',
      // saleType: 'new', // Optional: filter by new or recurring sales
  );

  $response = $sdk->analytics->retrieve(
      request: $request
  );

  if ($response->oneOf !== null) {
      // handle response
  }
  ```

  ```go Go theme={null}
  package main

  import(
      "context"
      dubgo "github.com/dubinc/dub-go"
      "github.com/dubinc/dub-go/models/operations"
      "log"
  )

  func main() {
      ctx := context.Background()

      s := dubgo.New(
          dubgo.WithSecurity("DUB_API_KEY"),
      )

      res, err := s.Analytics.Retrieve(ctx, operations.RetrieveAnalyticsRequest{
          Event: dubgo.String("sales"),
          GroupBy: dubgo.String("top_links"),
          LinkID: dubgo.String("-fold_xxx..."),
          Interval: dubgo.String("30d"),
          // SaleType: dubgo.String("new"), // Optional: filter by new or recurring sales
      })
      if err != nil {
          log.Fatal(err)
      }
      if res != nil {
          // handle response
      }
  }
  ```

  ```ruby Ruby theme={null}
  require 'dub'

  s = ::OpenApiSDK::Dub.new(
        security: ::OpenApiSDK::Shared::Security.new(
          token: "DUB_API_KEY",
        ),
      )

  req = ::OpenApiSDK::Operations::RetrieveAnalyticsRequest.new(
    event: "sales",
    groupBy: "top_links",
    linkId: "-fold_xxx...",
    interval: "30d",
    # saleType: "new", # Optional: filter by new or recurring sales
  )

  res = s.analytics.retrieve(req)

  if ! res.one_of.nil?
    # handle response
  end
  ```
</CodeGroup>

## Link folder analytics

The top link folders by event count, including folder names and IDs.

<CodeGroup>
  ```javascript Node.js theme={null}
  import { Dub } from "dub";

  export const dub = new Dub({
    token: process.env.DUB_API_KEY,
  });

  const result = await dub.analytics.retrieve({
    event: "sales",
    groupBy: "top_folders",
    interval: "30d",
    // saleType: "new" // Optional: filter by new or recurring sales
  });
  ```

  ```python Python theme={null}
  from dub import Dub

  with Dub(
      token="DUB_API_KEY",
  ) as d_client:
      res = d_client.analytics.retrieve(request={
          "event": "sales",
          "groupBy": "top_folders",
          "interval": "30d",
          # "saleType": "new",  # Optional: filter by new or recurring sales
      })
      print(res)
  ```

  ```php PHP theme={null}
  declare(strict_types=1);

  require 'vendor/autoload.php';

  use Dub;
  use Dub\Models\Operations;

  $sdk = Dub\Dub::builder()
      ->setSecurity('DUB_API_KEY')
      ->build();

  $request = new Operations\RetrieveAnalyticsRequest(
      event: 'sales',
      groupBy: 'top_folders',
      interval: '30d',
      // saleType: 'new', // Optional: filter by new or recurring sales
  );

  $response = $sdk->analytics->retrieve(
      request: $request
  );

  if ($response->oneOf !== null) {
      // handle response
  }
  ```

  ```go Go theme={null}
  package main

  import(
      "context"
      dubgo "github.com/dubinc/dub-go"
      "github.com/dubinc/dub-go/models/operations"
      "log"
  )

  func main() {
      ctx := context.Background()

      s := dubgo.New(
          dubgo.WithSecurity("DUB_API_KEY"),
      )

      res, err := s.Analytics.Retrieve(ctx, operations.RetrieveAnalyticsRequest{
          Event: dubgo.String("sales"),
          GroupBy: dubgo.String("top_folders"),
          Interval: dubgo.String("30d"),
          // SaleType: dubgo.String("new"), // Optional: filter by new or recurring sales
      })
      if err != nil {
          log.Fatal(err)
      }
      if res != nil {
          // handle response
      }
  }
  ```

  ```ruby Ruby theme={null}
  require 'dub'

  s = ::OpenApiSDK::Dub.new(
        security: ::OpenApiSDK::Shared::Security.new(
          token: "DUB_API_KEY",
        ),
      )

  req = ::OpenApiSDK::Operations::RetrieveAnalyticsRequest.new(
    event: "sales",
    groupBy: "top_folders",
    interval: "30d",
    # saleType: "new", # Optional: filter by new or recurring sales
  )

  res = s.analytics.retrieve(req)

  if ! res.one_of.nil?
    # handle response
  end
  ```
</CodeGroup>

You can also filter analytics for a specific folder (or set of folders) by passing the `folderId` parameter. It supports advanced filtering: single value, multiple values (comma-separated), or exclusion (prefix with `-`).

<CodeGroup>
  ```javascript Node.js theme={null}
  import { Dub } from "dub";

  export const dub = new Dub({
    token: process.env.DUB_API_KEY,
  });

  const result = await dub.analytics.retrieve({
    event: "sales",
    groupBy: "top_links",
    folderId: "fold_xxx...",
    interval: "30d",
    // saleType: "new" // Optional: filter by new or recurring sales
  });
  ```

  ```python Python theme={null}
  from dub import Dub

  with Dub(
      token="DUB_API_KEY",
  ) as d_client:
      res = d_client.analytics.retrieve(request={
          "event": "sales",
          "groupBy": "top_links",
          "folderId": "fold_xxx...",
          "interval": "30d",
          # "saleType": "new",  # Optional: filter by new or recurring sales
      })
      print(res)
  ```

  ```php PHP theme={null}
  declare(strict_types=1);

  require 'vendor/autoload.php';

  use Dub;
  use Dub\Models\Operations;

  $sdk = Dub\Dub::builder()
      ->setSecurity('DUB_API_KEY')
      ->build();

  $request = new Operations\RetrieveAnalyticsRequest(
      event: 'sales',
      groupBy: 'top_links',
      folderId: 'fold_xxx...',
      interval: '30d',
      // saleType: 'new', // Optional: filter by new or recurring sales
  );

  $response = $sdk->analytics->retrieve(
      request: $request
  );

  if ($response->oneOf !== null) {
      // handle response
  }
  ```

  ```go Go theme={null}
  package main

  import(
      "context"
      dubgo "github.com/dubinc/dub-go"
      "github.com/dubinc/dub-go/models/operations"
      "log"
  )

  func main() {
      ctx := context.Background()

      s := dubgo.New(
          dubgo.WithSecurity("DUB_API_KEY"),
      )

      res, err := s.Analytics.Retrieve(ctx, operations.RetrieveAnalyticsRequest{
          Event: dubgo.String("sales"),
          GroupBy: dubgo.String("top_links"),
          FolderID: dubgo.String("fold_xxx..."),
          Interval: dubgo.String("30d"),
          // SaleType: dubgo.String("new"), // Optional: filter by new or recurring sales
      })
      if err != nil {
          log.Fatal(err)
      }
      if res != nil {
          // handle response
      }
  }
  ```

  ```ruby Ruby theme={null}
  require 'dub'

  s = ::OpenApiSDK::Dub.new(
        security: ::OpenApiSDK::Shared::Security.new(
          token: "DUB_API_KEY",
        ),
      )

  req = ::OpenApiSDK::Operations::RetrieveAnalyticsRequest.new(
    event: "sales",
    groupBy: "top_links",
    folderId: "fold_xxx...",
    interval: "30d",
    # saleType: "new", # Optional: filter by new or recurring sales
  )

  res = s.analytics.retrieve(req)

  if ! res.one_of.nil?
    # handle response
  end
  ```
</CodeGroup>

## Link tag analytics

The top link tags by event count, including tag names and IDs.

<CodeGroup>
  ```javascript Node.js theme={null}
  import { Dub } from "dub";

  export const dub = new Dub({
    token: process.env.DUB_API_KEY,
  });

  const result = await dub.analytics.retrieve({
    event: "sales",
    groupBy: "top_link_tags",
    interval: "30d",
    // saleType: "new" // Optional: filter by new or recurring sales
  });
  ```

  ```python Python theme={null}
  from dub import Dub

  with Dub(
      token="DUB_API_KEY",
  ) as d_client:
      res = d_client.analytics.retrieve(request={
          "event": "sales",
          "groupBy": "top_link_tags",
          "interval": "30d",
          # "saleType": "new",  # Optional: filter by new or recurring sales
      })
      print(res)
  ```

  ```php PHP theme={null}
  declare(strict_types=1);

  require 'vendor/autoload.php';

  use Dub;
  use Dub\Models\Operations;

  $sdk = Dub\Dub::builder()
      ->setSecurity('DUB_API_KEY')
      ->build();

  $request = new Operations\RetrieveAnalyticsRequest(
      event: 'sales',
      groupBy: 'top_link_tags',
      interval: '30d',
      // saleType: 'new', // Optional: filter by new or recurring sales
  );

  $response = $sdk->analytics->retrieve(
      request: $request
  );

  if ($response->oneOf !== null) {
      // handle response
  }
  ```

  ```go Go theme={null}
  package main

  import(
      "context"
      dubgo "github.com/dubinc/dub-go"
      "github.com/dubinc/dub-go/models/operations"
      "log"
  )

  func main() {
      ctx := context.Background()

      s := dubgo.New(
          dubgo.WithSecurity("DUB_API_KEY"),
      )

      res, err := s.Analytics.Retrieve(ctx, operations.RetrieveAnalyticsRequest{
          Event: dubgo.String("sales"),
          GroupBy: dubgo.String("top_link_tags"),
          Interval: dubgo.String("30d"),
          // SaleType: dubgo.String("new"), // Optional: filter by new or recurring sales
      })
      if err != nil {
          log.Fatal(err)
      }
      if res != nil {
          // handle response
      }
  }
  ```

  ```ruby Ruby theme={null}
  require 'dub'

  s = ::OpenApiSDK::Dub.new(
        security: ::OpenApiSDK::Shared::Security.new(
          token: "DUB_API_KEY",
        ),
      )

  req = ::OpenApiSDK::Operations::RetrieveAnalyticsRequest.new(
    event: "sales",
    groupBy: "top_link_tags",
    interval: "30d",
    # saleType: "new", # Optional: filter by new or recurring sales
  )

  res = s.analytics.retrieve(req)

  if ! res.one_of.nil?
    # handle response
  end
  ```
</CodeGroup>

You can also filter analytics by one or more tags by passing the `tagIds` parameter. It supports advanced filtering: single value, multiple values, or exclusion (prefix with `-`).

<CodeGroup>
  ```javascript Node.js theme={null}
  import { Dub } from "dub";

  export const dub = new Dub({
    token: process.env.DUB_API_KEY,
  });

  const result = await dub.analytics.retrieve({
    event: "sales",
    groupBy: "top_links",
    tagId: ["tag_12345", "-tag_67890"],
    interval: "30d",
    // saleType: "new" // Optional: filter by new or recurring sales
  });
  ```

  ```python Python theme={null}
  from dub import Dub

  with Dub(
      token="DUB_API_KEY",
  ) as d_client:
      res = d_client.analytics.retrieve(request={
          "event": "sales",
          "groupBy": "top_links",
          "tagIds": ["tag_12345", "-tag_67890"],
          "interval": "30d",
          # "saleType": "new",  # Optional: filter by new or recurring sales
      })
      print(res)
  ```

  ```php PHP theme={null}
  declare(strict_types=1);

  require 'vendor/autoload.php';

  use Dub;
  use Dub\Models\Operations;

  $sdk = Dub\Dub::builder()
      ->setSecurity('DUB_API_KEY')
      ->build();

  $request = new Operations\RetrieveAnalyticsRequest(
      event: 'sales',
      groupBy: 'top_links',
      tagId: ['tag_12345', '-tag_67890'],
      interval: '30d',
      // saleType: 'new', // Optional: filter by new or recurring sales
  );

  $response = $sdk->analytics->retrieve(
      request: $request
  );

  if ($response->oneOf !== null) {
      // handle response
  }
  ```

  ```go Go theme={null}
  package main

  import(
      "context"
      dubgo "github.com/dubinc/dub-go"
      "github.com/dubinc/dub-go/models/operations"
      "log"
  )

  func main() {
      ctx := context.Background()

      s := dubgo.New(
          dubgo.WithSecurity("DUB_API_KEY"),
      )

      res, err := s.Analytics.Retrieve(ctx, operations.RetrieveAnalyticsRequest{
          Event: dubgo.String("sales"),
          GroupBy: dubgo.String("top_links"),
          TagID: []string{"tag_12345", "-tag_67890"},
          Interval: dubgo.String("30d"),
          // SaleType: dubgo.String("new"), // Optional: filter by new or recurring sales
      })
      if err != nil {
          log.Fatal(err)
      }
      if res != nil {
          // handle response
      }
  }
  ```

  ```ruby Ruby theme={null}
  require 'dub'

  s = ::OpenApiSDK::Dub.new(
        security: ::OpenApiSDK::Shared::Security.new(
          token: "DUB_API_KEY",
        ),
      )

  req = ::OpenApiSDK::Operations::RetrieveAnalyticsRequest.new(
    event: "sales",
    groupBy: "top_links",
    tagId: ["tag_12345", "-tag_67890"],
    interval: "30d",
    # saleType: "new", # Optional: filter by new or recurring sales
  )

  res = s.analytics.retrieve(req)

  if ! res.one_of.nil?
    # handle response
  end
  ```
</CodeGroup>
