14-day free trial · Any plan

Stop hand-coding
Slack messages.

Visual templates, versioned and team-owned. Send them with a single POST /v1/templates/send call.

No Block Kit JSON One REST API call Versioned templates
app.lithoblocks.com · interactive demo

// the problem

Stop putting Block Kit in your codebase.

Block Kit JSON in your repo means engineers own every copy change. LithoBlocks holds the template; your code only sends data.

Before

~60 lines · engineer-owned

// In your codebase
await slack.chat.postMessage({
  channel: '#alerts-prod',
  text: 'Stripe webhook processing failed',
  blocks: [
    {
      type: 'header',
      text: {
        type: 'plain_text',
        text: '🔴 Stripe webhook processing failed'
      }
    },
    {
      type: 'context',
      elements: [{
        type: 'mrkdwn',
        text: '*Service:* payment-service · *Env:* prod · *Region:* us-east-1'
      }]
    },
    {
      type: 'section',
      fields: [
        { type: 'mrkdwn', text: '*Events*\n14 in last 5m' },
        { type: 'mrkdwn', text: '*Event*\npayment.succeeded' },
        { type: 'mrkdwn', text: '*First seen*\n2:08 PM' },
        { type: 'mrkdwn', text: '*Last seen*\n2:13 PM' }
      ]
    },
    { type: 'divider' },
    {
      type: 'section',
      text: {
        type: 'mrkdwn',
        text: '*Top error:* WebhookProcessingException: timeout'
      }
    },
    {
      type: 'actions',
      elements: [
        {
          type: 'button',
          style: 'primary',
          action_id: 'ack',
          text: { type: 'plain_text', text: 'Acknowledge' }
        },
        {
          type: 'button',
          action_id: 'view',
          url: 'https://dash.acme.co/events',
          text: { type: 'plain_text', text: 'View events' }
        },
        {
          type: 'button',
          action_id: 'snooze',
          text: { type: 'plain_text', text: 'Snooze 1h' }
        }
      ]
    },
    {
      type: 'context',
      elements: [{
        type: 'mrkdwn',
        text: '📖 <https://docs.acme.co/runbooks|Runbook> · 📊 <https://dash.acme.co|Dashboard>'
      }]
    }
  ]
})
scroll for more · 60+ lines total

After

one REST call · data only

// In your codebase
await fetch('https://api.lithoblocks.com/v1/templates/send', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer $LB_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    template_id: 'tmpl_stripe_webhook_failed',
    channel_id: 'C0123456',
    data: {
      service: 'payment-service',
      env: 'production',
      region: 'us-east-1',
      events_affected: 14,
      event_type: 'payment.succeeded',
      window: '5 min',
      first_seen: '2:08 PM',
      last_seen: '2:13 PM',
      top_error: 'WebhookProcessingException: timeout',
      events_url: 'https://dash.acme.co/events'
    }
  })
})
// Response · 200 OK
{
  "success": true,
  "message_ts": "1715539834.001200",
  "channel": "C0123456",
  "remaining_credits": 986,
  "warnings": [],
  "slack_truncation": { "fields_truncated": 0 }
}
template lives in LithoBlocks · designed visually · ops, support, marketing can all edit

// what's in the box

Everything you'd build yourself. None of the work.

Six things you'd otherwise wire up across your codebase, automation tools, and a few internal docs.

01

Visual Block Kit builder

Drag blocks onto a canvas. Type real content. See the rendered message instantly. Exports valid Block Kit JSON if you want it.

02

Modals, integrated

Build interactive forms with inputs, selects, and date pickers. Wire a button on a message to open a modal, update the message on submit.

03

Message updates

When a button is clicked, update the original message to reflect what happened. One-click actions stay single-click. Get a built-in archive of who clicked what, how many people responded, and which items are still unattended.

04

Directives for summaries

Send an array of data, get an array of formatted blocks. Build digests and batched alerts without writing loops in your backend.

05

Versioned templates

Every template change is versioned. Edit in the builder, every workflow using that template picks up the change. Roll back if it broke something.

06

Simple REST API

One POST endpoint with bearer auth. Route a message to a channel ID, Slack user ID, or email. Get back the Slack message timestamp for updates later.

// call from anywhere

One endpoint. Any caller.

POST /v1/templates/send with a template ID, a destination, and your data. Call it from your backend, a Make scenario, a Zapier zap, GitHub Actions, or a bash script.

your-backend.ts
// your-backend.ts
await fetch('https://api.lithoblocks.com/v1/templates/send', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer $LB_API_KEY' },
  body: JSON.stringify({
    template_id: 'tmpl_stripe_webhook_failed',
    channel_id: 'C0123456',
    data: { ...alertData }
  })
})
terminal
curl -X POST https://api.lithoblocks.com/v1/templates/send \
  -H "Authorization: Bearer $LB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tmpl_payment_failed",
    "channel_id": "C0123456",
    "data": {"count": 14}
  }'
make.com / zapier
# Make.com scenario
TriggerHTTP POSTapi.lithoblocks.com/v1/templates/send

# Body
{ template_id, channel_id, data }

All three deliver the same template. Edit it once in LithoBlocks. All three pick up the change.

// pricing

Priced by messages, not seats.

Every plan includes unlimited templates, the visual builder, modal builder, message updates, and full API access.

Builder

$25/mo

250 messages / mo · 1 user

Team

popular

$50/mo

1,000 messages / mo · 3 users

Business

$250/mo

10,000 messages / mo · unlimited users

Move Slack messaging
out of your codebase.

Start your 14-day free trial. Any plan, any time.

Start free trial →