Skip to main content

PUT /api/v1/user/webhook/

Configures the webhook URL for receiving incoming messages from your campaigns. Auth: X-API-Key

Request Body

{
  "webhook_url": "https://your-app.com/seleqt-webhook"
}
To disable webhooks, send:
{
  "webhook_url": null
}

Response

{
  "success": true,
  "message": "Webhook URL updated successfully"
}

Example

curl -X PUT -H "X-API-Key: <key>" \
  -H "Content-Type: application/json" \
  -d '{"webhook_url": "https://your-app.com/seleqt-webhook"}' \
  "https://api.seleqt.ai/api/v1/user/webhook/"

Webhook Payload

When a new message is received, Seleqt will POST to your webhook URL:
{
  "event": "incoming_message",
  "message": {
    "id": 123,
    "message_id": "abc123",
    "message": "Hello there",
    "sent_by_lead": true,
    "sent_at": "2025-06-09T11:22:33Z",
    "created_at": "2025-06-09T11:22:33Z",
    "updated_at": "2025-06-09T11:22:33Z",
    "campaign": {
      "id": 456,
      "name": "Outbound - SaaS founders",
      "status": "ACTIVE"
    },
    "lead": {
      "id": 789,
      "first_name": "Alex",
      "last_name": "Doe",
      "profile_picture_url": "https://example.com/alex.jpg",
      "linkedin_profile_url": "https://www.linkedin.com/in/alex-doe/",
      "linkedin_public_id": "alex-doe",
      "job_title": "Head of Sales",
      "industry": "SaaS",
      "headline": "Helping teams close more deals",
      "email": "alex@example.com",
      "phone_number": "+1 555 0100",
      "location": "Amsterdam, NL",
      "status": "IN_REVIEW",
      "company": {
        "id": 321,
        "name": "Acme Inc",
        "linkedin_url": "https://www.linkedin.com/company/acme/",
        "logo_url": "https://example.com/logo.png",
        "website_url": "https://acme.com",
        "location": "Amsterdam, NL",
        "industry": "Software",
        "revenue": "$10M-$50M",
        "amount_of_employees": "51-200"
      },
      "custom_fields": { "plan": "pro" }
    }
  }
}

Security Notes

  • Consider hosting your endpoint behind a firewall that allows only Seleqt IPs
  • Implement idempotency by checking message.message_id on your side
  • No signature header is currently included in webhook payloads

Example Handler (Node.js/Express)

app.post("/seleqt-webhook", async (req, res) => {
  const { event, message } = req.body || {};

  if (event !== "incoming_message") {
    return res.status(200).send("ignored");
  }

  // Process the incoming message
  console.log(`New message from ${message.lead.first_name} ${message.lead.last_name}: ${message.message}`);

  // TODO: Add your business logic here

  res.status(200).send({ ok: true });
});