Slack contract signing with the Atlas API

Teams search for a Slack bot or slash command to send contracts when deals close in chat and nobody wants to open another SaaS tab. Atlas does not ship a Slack marketplace app today. You wire Slack events to POST /api/envelope and post review_url back to a channel.

> Share: "Slack triggers create. Atlas review page gates Send. Webhooks post signed status to the thread."

When Slack fits

Slack signing works when:

  • RevOps or founders live in Slack and only need a few contracts per week
  • Legal still wants a human to click Send on new document types
  • You already run a small Node or Python service for internal tools

Skip Slack glue when volume is high enough to justify a full CRM integration. HubSpot or Salesforce middleware scales better above a few dozen sends per month.

Architecture

Slack slash command or shortcut
  → Your server (verify Slack signing secret)
  → POST /api/envelope (PDF or DOCX URL or upload)
  → Post review_url to channel or DM
  → Human opens review, clicks Send
  → Signers email from Atlas
  → envelope.signed webhook → Slack thread update

Atlas owns field detection, sequential signing, and signed PDF output. Slack owns identity, channel context, and notifications.

Slash command flow

Register a slash command in your Slack app settings, for example /sign-contract. Point the request URL at your server.

Verify every inbound request with Slack's signing secret:

import crypto from 'crypto';

function verifySlack(req, signingSecret) {
  const ts = req.headers['x-slack-request-timestamp'];
  const sig = req.headers['x-slack-signature'];
  const base = `v0:${ts}:${req.rawBody}`;
  const hash = 'v0=' + crypto.createHmac('sha256', signingSecret).update(base).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(sig));
}

Parse the command text for signer email and optional document link:

/sign-contract jane@acme.com https://files.example.com/msa.pdf

Your handler calls Atlas:

curl -X POST https://atlaswork.ai/api/envelope \
  -H "Authorization: Bearer $ATLAS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: slack-${channel_id}-${user_id}-${Date.now()}" \
  -d '{
    "document_url": "https://files.example.com/msa.pdf",
    "webhook_url": "https://your-app.com/hooks/atlas-slack",
    "metadata": {
      "client_reference_id": "slack-C123",
      "external_id": "C123"
    },
    "parties": [
      { "email": "jane@acme.com", "name": "Jane Signer", "role": "Customer" }
    ]
  }'

Post the review_url in the channel with a Block Kit message:

{
  "blocks": [
    { "type": "section", "text": { "type": "mrkdwn", "text": "Envelope ready for review." } },
    { "type": "actions", "elements": [
      { "type": "button", "text": { "type": "plain_text", "text": "Open review" }, "url": "https://atlaswork.ai/review/..." }
    ]}
  ]
}

Do not auto-send from Slack unless counsel approved the template. First-time document types should always pass through review.

Bot mentions and shortcuts

For @AtlasBot sign this, use Slack file_shared events or message shortcuts. Download the attached PDF from Slack's files API, then upload to Atlas via multipart create:

curl -X POST https://atlaswork.ai/api/envelope \
  -H "Authorization: Bearer $ATLAS_API_KEY" \
  -H "Idempotency-Key: slack-file-${file_id}" \
  -F "file=@contract.pdf" \
  -F 'parties=[{"email":"buyer@example.com","name":"Buyer","role":"Customer"}]'

Store envelope_id in your database keyed by Slack thread_ts so webhook replies land in the right thread.

Webhook back to Slack

Set webhook_url on create. On envelope.signed, verify X-Atlas-Signature with HMAC-SHA256 using your API key, then call chat.postMessage:

await slack.chat.postMessage({
  channel: meta.slack_channel,
  thread_ts: meta.thread_ts,
  text: `Signed. Download: ${signedUrl}`,
});

Include metadata.client_reference_id at create so your handler can look up Slack context without scanning every envelope.

Trusted templates from Slack

After legal pins fields on a template, call POST /api/templates/{id}/send from Slack with prefill mapped from a modal. Template sends can skip review when your policy allows it. See API document templates.

Security checklist

  • Never put Atlas or Slack secrets in client-side Slack apps
  • Scope the bot to internal channels until flows are tested
  • Use Idempotency-Key on every create so Slack retries do not double-create
  • Log envelope_id and Slack user ID for audit

Comparison to native Slack e-sign apps

Marketplace apps embed another vendor's UI. Atlas keeps signing on Atlas pages with API-first control, webhooks you own, and MCP for agents that should prepare envelopes outside Slack. Many teams use Slack for the trigger and Atlas for the ceremony.

FAQ

Does Atlas post to Slack automatically? No. You implement the Slack API calls in your webhook handler.

Can signers sign inside Slack? Signers use Atlas sign links in email or browser. Embedding sign in Slack is possible in your portal but not a native Slack feature.

PDF and DOCX? Both work on create. DOCX converts to PDF for signing.

What if credits run out at Send? Send returns 402. Surface that in Slack so the reviewer buys credits at /dashboard/billing.

Sequential signing? Atlas signs parties in order. Your Slack message can show signed_count / total from GET /api/envelope/{id}/status.

API reference

Full route list and request schemas live at /dev. Start with E-signature API for the mental model, then use this guide for copy-paste examples.