Vercel Logo

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

  1. Link or create your Vercel project and deploy: pnpm dlx vercel --prod
  2. Update manifest with production URLs and reinstall
  3. 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:

  1. Deploy to Vercel with all environment variables
  2. Update manifest URLs to point to production domain
  3. Pass Slack's URL verification challenge
  4. Verify bot responds to mentions in a public channel
  5. Check logs show correlation IDs and structured data

Implementation hints:

  • Vercel automatically exposes env vars to your app
  • The /api/slack/events route must handle both verification and events
  • Watch for the verification challenge in Vercel Function logs
  • Test with a real @mention in 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 InformationApp Credentials
  • Bot token: App → Install AppBot User OAuth Token
AI Gateway Auth in Production

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_KEY in 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:

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

  1. Deploy to Vercel (link or create project):

    pnpm dlx vercel --prod

    Expected 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]
    
  2. 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"]
        }
      }
    }
  3. Reinstall app and verify URL:

    slack manifest update
    slack install

    In Slack App config, you'll see:

    Request URL: https://<your-app-domain>.vercel.sh/api/slack/events
    Your URL has been verified ✓
    
  4. 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 ✓
    
  5. 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_TOKEN starts with xoxb-
  • Check bot is in the channel (invite with /invite @bot-name)
  • Confirm manifest has app_mentions:read scope

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 production

Commit

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:

  1. Vercel deployment command:
pnpm dlx vercel --prod
  1. Updated manifest.json with production URL:
/slack-agent/manifest.json
```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"
      ]
    }
  }
}
  1. 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
  1. 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