How I Fixed a 4-Hour Link Expiration Problem with Relayhook
Let me share a frustrating problem I ran into last week that nearly derailed a client project – and the surprisingly elegant solution I found using Relayhook.
The Problem: Pipedream Connect Links Are Time Bombs
I was building an onboarding system where new users needed to connect their accounts to various services through Pipedream. The flow seemed simple enough:
- User signs up
- System sends welcome email with Pipedream Connect link
- User clicks link to authorize their integrations
- Everyone's happy
Except there was one massive problem: Pipedream Connect links expire after just 4 hours.
Think about that for a second. You send an onboarding email at 5 PM on Friday. Your user opens it Monday morning. Dead link. Frustrated user. Failed onboarding.
Even worse, some of our enterprise clients had approval workflows that could take days. By the time their IT department approved and clicked the link, it was long expired.
Why This Is Such a Pain
The Pipedream Connect API generates these authorization links with a call like this:
POST https://api.pipedream.com/v1/connect/accounts/auth
{
"app": "google_sheets",
"oauth_app_id": "oa_abc123",
"external_id": "user_123"
}
And you get back:
{
"authorization_url": "https://api.pipedream.com/connect/auth?token=eyJhbGc...",
"expires_at": "2024-03-15T20:00:00Z" // 4 hours from now
}
That expires_at
timestamp is non-negotiable. There's no parameter to extend it. You can't refresh it. After 4 hours, it's dead.
I tried a few workarounds:
- Generating links on a schedule: But then I'm sending multiple emails and confusing users
- Using a short-link service: Doesn't solve the underlying expiration
- Building a proxy server: Seemed like massive overkill for this one issue
The "Aha!" Moment with Relayhook
Then it hit me – what if instead of sending the Pipedream link directly, I sent a link that generates the Pipedream link when clicked?
Enter Relayhook. Here's how I made it work:
Step 1: Create a Persistent Link with Relayhook
Instead of the Pipedream link, I send users a Relayhook webhook URL that never expires:
https://api.relayhook.com/webhook/abc123xyz?user_id=user_123&app=google_sheets
This link can sit in their inbox for weeks. No expiration.
Step 2: Set Up the Zapier Flow
Here's where the magic happens. My Zap looks like this:
Trigger: New Relayhook Request
- Webhook catches the click
- Extracts user_id and app from query parameters
Action 1: Custom Code (Generate Fresh Pipedream Link)
// Zapier Code step
const response = await fetch('https://api.pipedream.com/v1/connect/accounts/auth', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + inputData.pipedream_api_key,
'Content-Type': 'application/json'
},
body: JSON.stringify({
app: inputData.app,
oauth_app_id: inputData.oauth_app_id,
external_id: inputData.user_id
})
});
const data = await response.json();
return { fresh_url: data.authorization_url };
Action 2: Relayhook Redirect
- Takes the fresh Pipedream URL
- Instantly redirects the user
Step 3: User Experience
From the user's perspective:
- They click the link in their email (even weeks later)
- Brief redirect through Relayhook (under 1 second)
- Land on a fresh, valid Pipedream Connect page
- Complete their authorization
They never know there was a 4-hour limitation. It just works.
The Technical Benefits
This approach solved more than just the expiration problem:
1. Better Analytics
Every click through Relayhook is logged. I can see exactly when users attempt to connect, even if they don't complete the flow.
2. Dynamic App Selection
I can change which integration they're connecting to based on their account settings, without sending new emails.
3. Error Handling
If the Pipedream API is down or returns an error, I can redirect to a friendly error page instead of showing a cryptic API error.
4. A/B Testing
I can randomly send users to different OAuth app configurations to test which permissions work best.
Implementation Tips
If you're implementing this pattern, here are some things I learned:
Security Considerations:
- Add a signed token to your Relayhook URL to prevent unauthorized use
- Validate the user_id against your database before generating the Pipedream link
- Consider rate limiting to prevent abuse
Performance Optimizations:
- Cache OAuth app IDs in Zapier Storage to avoid database lookups
- Use Zapier's built-in error handling to retry failed Pipedream API calls
- Set up monitoring to alert you if link generation starts failing
User Experience Enhancements:
- Add a loading page between Relayhook and Pipedream for smoother transition
- Include UTM parameters to track which email campaigns drive connections
- Set up a fallback URL if something goes wrong
The Bigger Picture
This solution highlighted something important: the tools we use often have arbitrary limitations that seem small but can break entire workflows. Pipedream's 4-hour expiration makes sense from their perspective (security, resource management), but it doesn't align with how businesses actually operate.
Relayhook fills this gap perfectly. It's not trying to replace Pipedream or Zapier – it's the glue that makes them work better together. It handles the edge cases that the big platforms won't.
Try It Yourself
If you're dealing with expiring links, webhook limitations, or need dynamic redirects, here's the setup:
- Sign up for Relayhook (the free tier is plenty for testing)
- Create a new Zap with the Relayhook trigger
- Add your link generation logic
- Use the Relayhook Redirect action
- Test with different timing scenarios
The whole setup takes about 15 minutes, and it's saved me countless support tickets from users with expired links.
What's Next?
I'm now using this pattern for other time-sensitive links:
- Stripe Checkout sessions (expire after 24 hours)
- Password reset flows with tight security windows
- Temporary file download links from S3
- Meeting scheduler links that need fresh availability
The pattern is always the same: permanent Relayhook link → generate fresh link → redirect. Simple, bulletproof, and invisible to users.
Have you run into similar timeout issues with API integrations? I'd love to hear how you solved them. Reach out on Twitter or drop me a note – always happy to talk shop about webhook workarounds.
Technical Stack Used:
- Relayhook for webhook handling and redirects
- Zapier for workflow orchestration
- Pipedream Connect API for integrations
- Node.js for custom code steps
Share this article