Skip to main content
Postiz integrates with popular URL shortening services to automatically shorten links in your social media posts, providing link tracking and analytics.

Supported Services

Postiz supports four URL shortening providers:
  • Dub - Open-source link management (recommended)
  • Short.io - Branded short links
  • Kutt.it - Self-hostable URL shortener
  • LinkDrip - Link shortening with drip campaigns
Postiz automatically selects the first configured provider. Configure only one service.

Provider Selection Priority

From short.link.service.ts:11-29:
const getProvider = (): ShortLinking => {
  if (process.env.DUB_TOKEN) {
    return new Dub();
  }
  
  if (process.env.SHORT_IO_SECRET_KEY) {
    return new ShortIo();
  }
  
  if (process.env.KUTT_API_KEY) {
    return new Kutt();
  }
  
  if (process.env.LINK_DRIP_API_KEY) {
    return new LinkDrip();
  }
  
  return new Empty(); // No shortening
};
Providers are checked in order: Dub → Short.io → Kutt → LinkDrip → Empty.

Configuration

Dub is an open-source link management platform with analytics.
1

Create Dub Account

  1. Visit dub.co or deploy your own instance
  2. Create an account and workspace
  3. Navigate to Settings → API
2

Generate API Token

  1. Click “Create API Key”
  2. Name it “Postiz Integration”
  3. Copy the token
3

Configure Custom Domain (Optional)

  1. Go to Domains → Add Domain
  2. Enter your custom domain (e.g., links.yourdomain.com)
  3. Add DNS records as instructed
  4. Wait for verification
4

Add to Environment

Add to your .env file:
DUB_TOKEN="dub_xxxxxxxxxxxxxxxxxxxx"
DUB_API_ENDPOINT="https://api.dub.co"  # Optional, defaults to this
DUB_SHORT_LINK_DOMAIN="dub.sh"  # Optional, use your custom domain
For self-hosted Dub:
DUB_TOKEN="your-api-token"
DUB_API_ENDPOINT="https://your-dub-instance.com/api"
DUB_SHORT_LINK_DOMAIN="your-short-domain.com"
5

Restart Postiz

docker compose restart

Short.io

Short.io is a commercial URL shortening service with branded links.
1

Create Short.io Account

Visit short.io and create an account.
2

Get API Key

  1. Go to Settings → Integrations & API
  2. Copy your secret API key
3

Configure Environment

Add to your .env file:
SHORT_IO_SECRET_KEY="your-secret-key"
Short.io uses short.io domain by default (hardcoded in provider).
4

Restart Postiz

docker compose restart

Kutt.it

Kutt is a self-hostable open-source URL shortener.
1

Deploy Kutt Instance

Follow the Kutt deployment guide or use the hosted version at kutt.it.
2

Get API Key

  1. Log in to your Kutt instance
  2. Go to Settings → API
  3. Generate and copy your API key
3

Configure Environment

Add to your .env file:
KUTT_API_KEY="your-api-key"
KUTT_API_ENDPOINT="https://kutt.it/api/v2"  # Optional, defaults to this
KUTT_SHORT_LINK_DOMAIN="kutt.it"  # Optional, use your custom domain
For self-hosted Kutt:
KUTT_API_KEY="your-api-key"
KUTT_API_ENDPOINT="https://your-kutt-instance.com/api/v2"
KUTT_SHORT_LINK_DOMAIN="your-short-domain.com"
4

Restart Postiz

docker compose restart

LinkDrip

LinkDrip provides URL shortening with marketing automation features.
1

Create LinkDrip Account

Visit linkdrip.com and create an account.
2

Get API Key

  1. Navigate to Settings → API
  2. Generate and copy your API key
3

Configure Environment

Add to your .env file:
LINK_DRIP_API_KEY="your-api-key"
LINK_DRIP_API_ENDPOINT="https://api.linkdrip.com/v1/"  # Optional
LINK_DRIP_SHORT_LINK_DOMAIN="dripl.ink"  # Optional
4

Restart Postiz

docker compose restart
LinkDrip integration currently has limited analytics support in Postiz.

Automatic URL Detection

Postiz automatically detects and shortens URLs in your posts:
// From short.link.service.ts:54-94
async convertTextToShortLinks(id: string, messagesList: string[]) {
  if (ShortLinkService.provider.shortLinkDomain === 'empty') {
    return messagesList;
  }
  
  const urlRegex = /(https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/\/=]*))/gm;
  
  return Promise.all(
    messages.map(async (text) => {
      const urls = uniq(text.match(urlRegex));
      if (!urls) {
        return text;
      }
      
      const replacementMap: Record<string, string> = {};
      
      await Promise.all(
        urls.map(async (url) => {
          if (url.indexOf(ShortLinkService.provider.shortLinkDomain) === -1) {
            replacementMap[url] = await ShortLinkService.provider.convertLinkToShortLink(id, url);
          } else {
            replacementMap[url] = url; // Already shortened
          }
        })
      );
      
      return text.replace(urlRegex, (url) => replacementMap[url]);
    })
  );
}
// From dub.ts:37-51
async convertLinkToShortLink(id: string, link: string) {
  return (
    await fetch(`${DUB_API_ENDPOINT}/links`, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.DUB_TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        url: link,
        tenantId: id,
        domain: this.shortLinkDomain,
      }),
    }).then(res => res.json())
  ).shortLink;
}
Postiz retrieves click statistics for shortened links:
// From short.link.service.ts:130-150
async getStatistics(messages: string[]) {
  if (ShortLinkService.provider.shortLinkDomain === 'empty') {
    return [];
  }
  
  const mergeMessages = messages.join(' ');
  const regex = new RegExp(
    `https?://${ShortLinkService.provider.shortLinkDomain.replace('.', '\\.')}/[^\\s]*`,
    'g'
  );
  const urls = striptags(mergeMessages).match(regex);
  
  if (!urls) {
    return [];
  }
  
  return ShortLinkService.provider.linksStatistics(urls);
}

Analytics by Provider

// From dub.ts:16-35
async linksStatistics(links: string[]) {
  return Promise.all(
    links.map(async (link) => {
      const response = await fetch(
        `${DUB_API_ENDPOINT}/links/info?domain=${
          this.shortLinkDomain
        }&key=${link.split('/').pop()}`,
        {
          headers: {
            Authorization: `Bearer ${process.env.DUB_TOKEN}`,
          },
        }
      ).then(res => res.json());
      
      return {
        short: link,
        original: response.url,
        clicks: response.clicks,
      };
    })
  );
}
LinkDrip provider currently returns empty analytics in Postiz implementation.
Postiz can optionally prompt users before shortening LinkedIn links:
// From short.link.service.ts:35-52
askShortLinkedin(messages: string[]): boolean {
  if (ShortLinkService.provider.shortLinkDomain === 'empty') {
    return false;
  }
  
  const mergeMessages = messages.join(' ');
  const urlRegex = /(https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/\/=]*))/gm;
  const urls = mergeMessages.match(urlRegex);
  
  if (!urls) {
    return false;
  }
  
  return urls.some(
    (url) => url.indexOf(ShortLinkService.provider.shortLinkDomain) === -1
  );
}
This prompts users only if the post contains URLs that aren’t already shortened. To disable URL shortening:
  1. Remove or comment out all short link provider variables from .env:
    # DUB_TOKEN=""
    # SHORT_IO_SECRET_KEY=""
    # KUTT_API_KEY=""
    # LINK_DRIP_API_KEY=""
    
  2. Restart Postiz:
    docker compose restart
    
Postiz will use the Empty provider and skip URL shortening.

Testing

1

Create Test Post

Create a post with a long URL:
Check out our website: https://example.com/very/long/path/to/content?utm_source=test
2

Schedule Post

Schedule the post to any connected social account.
3

Verify Shortening

Check that the URL was shortened in the scheduled post preview.
4

Check Analytics

After posting, view link analytics in your short link provider dashboard.

Troubleshooting

If you see authentication errors:
  1. Dub: Verify token is valid and not expired
  2. Short.io: Check secret key is correct
  3. Kutt: Ensure API key has proper permissions
  4. LinkDrip: Verify API key is active
Test API access:
# Dub
curl -H "Authorization: Bearer $DUB_TOKEN" https://api.dub.co/links

# Kutt
curl -H "X-API-Key: $KUTT_API_KEY" https://kutt.it/api/v2/links
For custom domain issues:
  1. DNS Not Configured: Verify DNS records are correct
  2. Not Verified: Wait for domain verification to complete
  3. Wrong Domain Variable: Ensure *_SHORT_LINK_DOMAIN matches your custom domain
  4. SSL Issues: Ensure HTTPS is configured for custom domain
Check domain status in your provider’s dashboard.
If click analytics are missing:
  1. LinkDrip: Analytics not implemented in Postiz for this provider
  2. API Errors: Check logs for analytics API failures
  3. No Clicks: Verify links have actually been clicked
  4. Time Delay: Some providers have delays in analytics reporting
If you hit rate limits:
  1. Upgrade Plan: Consider upgrading your provider plan
  2. Reduce Frequency: Limit number of posts with links
  3. Batch Processing: Postiz already batches link creation
  4. Self-Host: Use self-hosted Dub or Kutt for unlimited links

Self-Hosted Recommendations

For production deployments, consider self-hosting:
  • Open-source and actively maintained
  • Full analytics and dashboard
  • Easy deployment with Docker
  • Custom domain support
  • No API rate limits
Deploy Dub →

Kutt

  • Lightweight and simple
  • Self-hosted with full control
  • Custom domain support
  • API-first design
Deploy Kutt →

Best Practices

Use branded short domains (e.g., go.yourbrand.com) instead of generic domains for better brand recognition and trust.
  • Configure only one provider to avoid confusion
  • Use custom domains for professional appearance
  • Monitor analytics regularly for engagement insights
  • Set up proper DNS records for custom domains
  • Test links before major campaigns
  • Keep API keys secure and rotate regularly
  • Monitor rate limits and upgrade plans as needed

Security Considerations

Never expose short link API keys in client-side code or commit them to version control.
  • Store API keys in environment variables only
  • Use HTTPS for all short link redirects
  • Monitor for suspicious click patterns
  • Implement click fraud detection (via provider)
  • Regularly audit shortened links
  • Set expiration dates for temporary campaigns
  • Use link passwords for sensitive content (if supported)

Next Steps

After configuring short links:

Build docs developers (and LLMs) love