Skip to main content
When creating links programmatically with Dub, you might want a way to associate them with a user or other identifiers in your system. There are a few ways to do this, depending on your data structure:
MethodTypeDescriptionUse case
External IDOne-to-oneA unique identifier for a link within your system.Associating referral links with users in your system.
Tenant IDOne-to-manyThe ID of the tenant that created the link.Grouping all links created by a user/team in your system.
TagsMany-to-manyGrouping links by tagsOrganizing links by campaign / user / various for flexible, multi-dimensional filtering and reporting

External ID

In certain scenarios, it is essential to identify links within your system. For instance, you may need to associate a link with a user without storing the Dub link ID directly in your database (e.g. for referral links). The externalId field serves this purpose effectively. It acts as a unique identifier within your database, allowing you to associate it with a corresponding link in Dub’s system. Dub allows you to create links using an externalId and subsequently retrieve them by the same identifier.
externalId should be a unique value across your workspace. Trying to create a link with an externalId that already exists will result in a 409 conflict error error.
Here is an example of how to create a link with an externalId:
import { Dub } from "dub";

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

const link = await dub.links.create({
  url: "https://google.com",
  externalId: "12345",
});
package main

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

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

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

  res, err := s.Links.Create(ctx, &operations.CreateLinkRequestBody{
    URL: "https://google.com",
    ExternalId: "12345",
  })

  if err != nil {
    log.Fatal(err)
  }

  if res != nil {
    // handle response
  }
}
import os
import dub
from dub.models import operations

d = dub.Dub(
  token=os.environ['DUB_API_KEY'],
)

res = d.links.create(request={
  "url": "https://google.com",
  "external_id": "12345",
})
require 'dub'

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

req = ::OpenApiSDK::Operations::CreateLinkRequestBody.new(
  url: "https://google.com",
  external_id: "12345",
)
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\CreateLinkRequestBody(
  url: 'https://google.com',
  externalId: '12345',
);

$response = $sdk->links->create(
  request: $request
);
curl --request POST \
  --url https://api.dub.co/links \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "url": "https://google.com",
    "external_id": "12345"
  }'
Let’s see how to retrieve a link by its externalId:
import { Dub } from "dub";

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

const link = await dub.links.get({
  externalId: "12345",
});
package main

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

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

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

  res, err := s.Links.Get(ctx, operations.GetLinkInfoRequest{
    ExternalID: dubgo.String("12345"),
  })
}
import os
import dub
from dub.models import operations

d = dub.Dub(
  token=os.environ['DUB_API_KEY'],
)

res = d.links.get(request={
  "external_id": "12345",
})
require 'dub'

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

req = ::OpenApiSDK::Operations::GetLinkInfoRequest.new(
  external_id: "12345",
)

res = s.links.get(req)
declare(strict_types=1);

require 'vendor/autoload.php';

use Dub;
use Dub\Models\Operations;

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

$response = $sdk->links->get(
  externalId: '12345'
);
curl --request GET \
  --url https://api.dub.co/links/info?external_id=12345 \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json'
In addition to updating a link by its linkId, you can also update a link by its externalId.
Make sure to prefix the externalId with ext_. For example, if your externalId is 12345, you should pass ext_12345.
import { Dub } from "dub";

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

const link = await dub.links.update("ext_12345", {
  url: "https://www.google.uk", // new URL
});
package main

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

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

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

  res, err := s.Links.Update(ctx, "ext_12345", &operations.UpdateLinkRequestBody{
    URL: "https://www.google.uk", // new URL
  })

  if err != nil {
    log.Fatal(err)
  }

  if res != nil {
    // handle response
  }
}
import os
import dub
from dub.models import operations

d = dub.Dub(
  token=os.environ['DUB_API_KEY'],
)

res = dub.links.update(link_id="ext_12345", request_body={
  "url": "https://www.google.uk", // new URL
})
require 'dub'

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

res = s.links.update(link_id="ext_12345", request_body={
  "url": "https://www.google.uk", // new URL
})
declare(strict_types=1);

require 'vendor/autoload.php';

use Dub;
use Dub\Models\Operations;

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

$requestBody = new Operations\UpdateLinkRequestBody(
  url: 'https://www.google.uk', // new URL
);

$response = $sdk->links->update(
  linkId: 'ext_12345',
  requestBody: $requestBody
);
curl --request PATCH \
  --url https://api.dub.co/links/ext_12345 \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{"url": "https://www.google.uk"}'

Retrieve analytics by externalId

You can also retrieve analytics for a link by its externalId. This is helpful for fetching the analytics for a given link using the unique identifier from your system.
import { Dub } from "dub";

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

const analytics = await dub.analytics.retrieve({
  externalId: "ext_12345",
});
package main

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

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

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

  res, err := s.Analytics.Retrieve(ctx, operations.RetrieveAnalyticsRequest{
    ExternalID: dubgo.String("ext_12345"),
  })
}
import os
import dub
from dub.models import operations

d = dub.Dub(
  token=os.environ['DUB_API_KEY'],
)

res = dub.analytics.retrieve(request={
  "external_id": "ext_12345",
})
require 'dub'

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

req = ::OpenApiSDK::Operations::RetrieveAnalyticsRequest.new(
  external_id: "ext_12345",
)

res = s.analytics.retrieve(req)
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(
  externalId: "ext_12345",
);

$response = $sdk->analytics->retrieve(
  request: $request
);
curl --request GET \
  --url https://api.dub.co/analytics?external_id=ext_12345 \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json'

Tenant ID

The ID of the tenant that created the link inside your system. If set, it can be used to fetch all links for a tenant. This is useful if you have a system that lets your users create their own links, and you want to group them on a tenant level. Let’s see how to create a link with a tenant ID:
import { Dub } from "dub";

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

const link = await dub.links.create({
  url: "https://google.com",
  tenantId: "12345",
});
package main

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

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

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

  res, err := s.Links.Create(ctx, &operations.CreateLinkRequestBody{
    URL: "https://google.com",
    TenantId: "12345",
  })

  if err != nil {
    log.Fatal(err)
  }

  if res != nil {
    // handle response
  }
}
import os
import dub
from dub.models import operations

d = dub.Dub(
  token=os.environ['DUB_API_KEY'],
)

res = d.links.create(request={
  "url": "https://google.com",
  "tenant_id": "12345",
})
require 'dub'

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

req = ::OpenApiSDK::Operations::CreateLinkRequestBody.new(
  url: "https://google.com",
  tenant_id: "12345",
)
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\CreateLinkRequestBody(
  url: 'https://google.com',
  tenantId: '12345',
);

$response = $sdk->links->create(
  request: $request
);
curl --request POST \
  --url https://api.dub.co/links \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "url": "https://google.com",
    "external_id": "12345"
  }'
Here is how to retrieve links by tenant ID:
import { Dub } from "dub";

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

const result = await dub.links.list({
  tenantId: "12345",
});
package main

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

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

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

  res, err := s.Links.List(ctx, operations.GetLinksRequest{
    TenantId: dubgo.String("12345"),
  })
}
import os
import dub
from dub.models import operations

d = dub.Dub(
  token=os.environ['DUB_API_KEY'],
)

res = s.links.list(request={
  "tenant_id": "12345",
})
require 'dub'

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

req = ::OpenApiSDK::Operations::GetLinksRequest.new(
  tenant_id: "12345",
)

res = s.links.list(req)
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\GetLinksRequest(
  tenantId: "12345",
);

$responses = $sdk->links->list(
  request: $request
);

curl --request GET \
  --url https://api.dub.co/links?tenantId=12345 \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json'

Retrieve analytics by tenantId

You can retrieve analytics by tenantId by passing the tenantId prop. This is helpful for fetching the analytics for all the links under a specific tenant, or the total analytics for a tenant.
import { Dub } from "dub";

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

const analytics = await dub.analytics.retrieve({
  tenantId: "12345",
});
package main

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

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

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

  res, err := s.Analytics.Retrieve(ctx, operations.RetrieveAnalyticsRequest{
    TenantId: dubgo.String("12345"),
  })
}
import os
import dub
from dub.models import operations

d = dub.Dub(
  token=os.environ['DUB_API_KEY'],
)

res = dub.analytics.retrieve(request={
  "tenant_id": "12345",
})
require 'dub'

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

req = ::OpenApiSDK::Operations::RetrieveAnalyticsRequest.new(
  tenant_id: "12345",
)

res = s.analytics.retrieve(req)
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(
  tenantId: "12345",
);

$response = $sdk->analytics->retrieve(
  request: $request
);
curl --request GET \
  --url https://api.dub.co/analytics?tenantId=12345 \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json'

Tags

Tags are a great way to organize your links on Dub. With tags, you can: You can use either pass the tag ID or tag name to create a link with tags.
import { Dub } from "dub";

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

const link = await dub.links.create({
  url: "https://example.com",
  tagIds: ["clux0rgak00011..."],
});
package main

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

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

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

  res, err := s.Links.Create(ctx, &operations.CreateLinkRequestBody{
    URL: "https://example.com",
    TagIds: []string{"clux0rgak00011..."},
  })

  if err != nil {
    log.Fatal(err)
  }

  if res != nil {
    // handle response
  }
}
import os
import dub
from dub.models import operations

d = dub.Dub(
  token=os.environ['DUB_API_KEY'],
)

res = d.links.create(request={
  "url": "https://example.com",
  "tag_ids": ["clux0rgak00011..."],
})
require 'dub'

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

req = ::OpenApiSDK::Operations::CreateLinkRequestBody.new(
  url: "https://example.com",
  tag_ids: ["clux0rgak00011..."],
)
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\CreateLinkRequestBody(
  url: 'https://example.com',
  tagIds: ['clux0rgak00011...'],
);

$response = $sdk->links->create(
  request: $request
);
curl --request POST \
  --url https://api.dub.co/links \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "url": "https://example.com",
    "tagIds": ["clux0rgak00011..."]
  }'
You can retrieve links by tag by tags.
import { Dub } from "dub";

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

const result = await dub.links.list({
  tagNames: ["tag1"],
});
package main

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

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

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

  res, err := s.Links.List(ctx, operations.GetLinksRequest{
    TagNames: []string{"tag1"},
  })
}
import os
import dub
from dub.models import operations

d = dub.Dub(
  token=os.environ['DUB_API_KEY'],
)

res = s.links.list(request={
  "tag_names": ["tag1"],
})
require 'dub'

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

req = ::OpenApiSDK::Operations::GetLinksRequest.new(
  tag_names: ["tag1"],
)

res = s.links.list(req)
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\GetLinksRequest(
  tagNames: ["tag1"],
);

$responses = $sdk->links->list(
  request: $request
);

curl --request GET \
  --url https://api.dub.co/links?tagNames=tag1 \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json'

Retrieve analytics by tags

You can retrieve analytics for a tag (or multiple tags) by passing the tagIds prop. This is helpful for fetching the analytics for all the links under a specific tag, or the total analytics for a tag (or multiple tags).
import { Dub } from "dub";

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

const analytics = await dub.analytics.retrieve({
  tagIds: ["tag_xxx"],
});
package main

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

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

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

  res, err := s.Analytics.Retrieve(ctx, operations.RetrieveAnalyticsRequest{
    TagIds: []string{"tag_xxx"},
  })
}
import os
import dub
from dub.models import operations

d = dub.Dub(
  token=os.environ['DUB_API_KEY'],
)

res = dub.analytics.retrieve(request={
  "tag_ids": ["tag_xxx"],
})
require 'dub'

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

req = ::OpenApiSDK::Operations::RetrieveAnalyticsRequest.new(
  tag_ids: ["tag_xxx"],
)

res = s.analytics.retrieve(req)
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(
  tagIds: ["tag_xxx"],
);

$response = $sdk->analytics->retrieve(
  request: $request
);
curl --request GET \
  --url https://api.dub.co/analytics?tagIds=tag_xxx \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json'