Deploy Your Bot to Production on Vercel
Running slack run locally is fine for development, but your bot needs to be available 24/7. When a major incident hits and the team needs instant AI assistance, your bot better be online. Production deployment means real URLs, proper secrets management, and zero downtime during Slack's URL verification handshake.
Outcome
Deploy your bot to Vercel with working event handling, proper environment variables, and a verified Slack Events URL.
Fast Track
- Link or create your Vercel project and deploy:
pnpm dlx vercel --prod - Update manifest with production URLs and reinstall
- Verify bot responds in a real Slack channel
Deployment Pipeline
┌─────────────────────────────────────────────────────────────────┐
│ Local → Production Flow │
└─────────────────────────────────────────────────────────────────┘
Local Development Production Deployment
↓ ↓
┌─────────────────┐ ┌─────────────────┐
│ slack run │ │ pnpm dlx vercel │
│ (ngrok tunnel) │ │ --prod │
└─────────────────┘ └─────────────────┘
↓ ↓
┌─────────────────┐ ┌─────────────────┐
│ manifest.json │ UPDATE URLs │ manifest.json │
│ localhost:3000 │ ──────────────→│ yourapp.vercel │
│ │ │ .app │
└─────────────────┘ └─────────────────┘
↓ ↓
┌─────────────────┐ ┌─────────────────┐
│ Test locally │ │ Slack URL │
│ @bot ping │ │ Verification │
│ ✓ works │ │ Challenge │
└─────────────────┘ └─────────────────┘
↓
┌─────────────────┐
│ Production │
│ Bot Live │
│ @bot ping ✓ │
└─────────────────┘
Environment Variables Flow:
Local: .env file → process.env
Production: Vercel Dashboard → Function runtime
Building on Previous Lessons
This deployment brings together every pattern from the course into production:
- From Project Setup: You already have your own repo (and likely a Vercel project from the Deploy button); now you’ll make that deployment production-ready
- From repository flyover: Stateless request-response architecture enables horizontal scaling - Vercel can spawn thousands of function instances
- From correlation middleware: Correlation middleware tracks requests across distributed function executions
- From ack semantics: Ack-first pattern prevents timeouts in serverless environments with cold starts
- From slash commands: All interaction surfaces (commands, shortcuts, modals) work identically in serverless
- From AI tools: Active context fetching and tool calls (no shared memory) are essential for stateless functions
- From system prompts: AI orchestration with retries, status, and fallbacks handles real production traffic
- Production reality: Each Slack event spawns a fresh function execution - zero shared state, perfect for serverless deployment
Hands-On Exercise 5.1
Deploy your bot to Vercel and verify it handles production traffic:
Requirements:
- Deploy to Vercel with all environment variables
- Update manifest URLs to point to production domain
- Pass Slack's URL verification challenge
- Verify bot responds to mentions in a public channel
- Check logs show correlation IDs and structured data
Implementation hints:
- Vercel automatically exposes env vars to your app
- The
/api/slack/eventsroute must handle both verification and events - Watch for the verification challenge in Vercel Function logs
- Test with a real
@mentionin a non-DM channel
Environment variables needed:
SLACK_BOT_TOKEN=xoxb-...
SLACK_SIGNING_SECRET=...For production you may be using a different Slack app than your sandbox one (for example, if slack manifest update created a new app). In any case, get the correct secrets from your Slack app config at https://api.slack.com/apps:
- Signing Secret: App → Basic Information → App Credentials
- Bot token: App → Install App → Bot User OAuth Token
In local development, you configure AI_GATEWAY_API_KEY so the AI SDK can talk to Vercel AI Gateway. In production on Vercel, the recommended path is to rely on the platform’s automatically generated OIDC token – the AI SDK will pick this up as long as you use plain string model IDs (for example, 'openai/gpt-4.1' or 'xai/grok-3') and have Gateway enabled for the project.
Sharp edges to watch out for:
- You won’t see the OIDC token in
process.env– it’s injected at the platform/runtime level. - If you set
AI_GATEWAY_API_KEYin production, Gateway will use that key instead of OIDC (which is fine, but now you own key rotation). - Make sure you’re deploying to the same Vercel project you configured Gateway for, or you’ll see auth errors even though “it works locally”.
To inspect this behavior later:
- Open your project’s security settings: Secure Backend Access with OIDC Federation
- Open the AI Gateway dashboard: AI Gateway Dashboard
See the official docs for details: AI Gateway Authentication – OIDC token and this AI SDK course's setup guide’s Gateway step (AI SDK dev setup – Step 4).
Try It
-
Deploy to Vercel (link or create project):
pnpm dlx vercel --prodExpected output:
Vercel CLI 28.5.5 ? Set up and deploy "<PATH_TO_YOUR_REPO>"? [Y/n] y ? Which scope do you want to deploy to? Your Team # If you already created a project via the Deploy with Vercel button, choose that existing project here. # Otherwise, create a new project for this repo. ? What's your project's name? slack-bot-prod ? In which directory is your code located? ./ Auto-detected Project Settings (Nitro): - Build Command: npm run build - Output Directory: .output - Development Command: npm run dev ? Want to override the settings? [y/N] n 🔗 Linked to yourteam/slack-bot-prod (created .vercel) 🔍 Inspect: https://vercel.com/yourteam/slack-bot-prod/abc123 ✅ Production: https://slack-bot-prod.vercel.app [21s] -
Update manifest.json:
{ "features": { "app_home": { "home_tab_enabled": false, "messages_tab_enabled": true } }, "oauth_config": { "scopes": { "bot": [ "app_mentions:read", "channels:history", "chat:write", "groups:history", "im:history", "mpim:history" ] } }, "settings": { "event_subscriptions": { "request_url": "https://<your-app-domain>.vercel.sh/api/slack/events", "bot_events": ["app_mention", "message.channels", "message.groups", "message.im", "message.mpim"] } } } -
Reinstall app and verify URL:
slack manifest update slack installIn Slack App config, you'll see:
Request URL: https://<your-app-domain>.vercel.sh/api/slack/events Your URL has been verified ✓ -
Test in production channel:
You: @bot-name what's the deployment status? Bot: I'm successfully deployed to production! Here's my status: - Environment: Production (Vercel) - Correlation ID: ev09E5EDA89M_1234567890.123456 - Response time: 1.2s - All systems operational ✓ -
Verify logs in Vercel dashboard:
[INFO] bolt-app { correlationId: 'ev09E5EDA89M_1234567890.123456', event_id: 'Ev09E5EDA89M', type: 'app_mention', channel: 'C09D4DG727P', thread_ts: '1234567890.123456', user: 'U0123ABCDEF' } Processing app_mention event [INFO] bolt-app { correlationId: 'ev09E5EDA89M_1234567890.123456', operation: 'respondToMessage', model: 'openai/gpt-4o-mini', promptTokens: 156, completionTokens: 47, latencyMs: 892 } AI response generated successfully
Troubleshooting
URL Verification Fails:
- Check your signing secret is correctly set in Vercel env vars
- Ensure the route is
/api/slack/events(not/api/events) - Look for the challenge parameter in Vercel Function logs
Bot Doesn't Respond:
- Verify
SLACK_BOT_TOKENstarts withxoxb- - Check bot is in the channel (invite with
/invite @bot-name) - Confirm manifest has
app_mentions:readscope
Environment Variables Missing:
# List current env vars for your project
pnpm dlx vercel env ls
# Add missing Slack secrets (production)
pnpm dlx vercel env add SLACK_BOT_TOKEN production
pnpm dlx vercel env add SLACK_SIGNING_SECRET production
# (Optional) Add AI gateway key if you want to override OIDC-based auth
pnpm dlx vercel env add AI_GATEWAY_API_KEY productionCommit
git add -A
git commit -m "feat(deploy): production deployment to Vercel with URL verification
- Configure Vercel deployment with Nitro preset
- Update manifest URLs to production domain
- Handle Slack URL verification challenge
- Verify bot responds in production channels
- Structured logs with correlation IDs working"Done-When
- Bot deployed to Vercel and accessible via public URL
- Slack Events URL verified (green checkmark in app config)
- Bot responds to mentions in production channel
- Logs show correlation IDs and structured fields
- All environment variables properly configured
Solution
The key parts for production deployment:
- Vercel deployment command:
pnpm dlx vercel --prod- Updated manifest.json with production URL:
```json title="/slack-agent/manifest.json" {15}
{
"display_information": {
"name": "AI Assistant Bot",
"description": "Production AI assistant with context awareness",
"background_color": "#1a1a2e"
},
"features": {
"app_home": {
"home_tab_enabled": false,
"messages_tab_enabled": true
}
},
"settings": {
"event_subscriptions": {
"request_url": "https://<your-app-domain>.vercel.sh/api/slack/events",
"bot_events": [
"app_mention",
"message.channels",
"message.groups",
"message.im",
"message.mpim"
]
}
},
"oauth_config": {
"scopes": {
"bot": [
"app_mentions:read",
"channels:history",
"chat:write",
"groups:history",
"im:history",
"mpim:history"
]
}
}
}- Environment variables in Vercel: All secrets are added through Vercel dashboard or CLI:
pnpm dlx vercel env add SLACK_BOT_TOKEN production
pnpm dlx vercel env add SLACK_SIGNING_SECRET production- Verification of deployment: Check Function logs in Vercel dashboard for:
- URL verification challenge handled
- Events being received
- Correlation IDs in structured logs
- Response times under 3 seconds
Key Takeaways
- Production deployment requires proper URL configuration in both Vercel and Slack
- The URL verification handshake must complete within 3 seconds
- Environment variables must be set in Vercel, not just locally
- Structured logging with correlation IDs is essential for debugging production issues
- Always test in a real channel after deployment
Was this helpful?