Skip to main content
Arcanflows

Webhooks & Events API

Outgoing webhooks, incoming webhooks, event subscriptions, and real-time event streaming.

Overview

The Webhooks & Events system provides both outgoing webhooks (push notifications to your servers) and incoming webhooks (receive data from external services). The event system allows fine-grained subscriptions, event tracing, and workflow triggers.


Outgoing Webhooks

Outgoing webhooks send HTTP POST requests to your endpoints when events occur in Arcanflows.

List Webhooks

GET /api/v1/webhooks

Query Parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
per_pageintegerItems per page (default: 20)
activebooleanFilter by active status

Create Webhook

POST /api/v1/webhooks

Request Body:

FieldTypeRequiredDescription
urlstringYesHTTPS endpoint URL
eventsstring[]YesEvent types to subscribe to
activebooleanNoEnable immediately (default: true)
descriptionstringNoHuman-readable description
headersobjectNoCustom headers to include
bash
curl -X POST /api/v1/webhooks \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhook",
    "events": ["agent.chat.completed", "workflow.execution.completed"],
    "description": "Production webhook",
    "active": true
  }'

Response:

json
{
  "id": "wh_abc123",
  "url": "https://your-server.com/webhook",
  "events": ["agent.chat.completed", "workflow.execution.completed"],
  "active": true,
  "secret": "whsec_a1b2c3d4e5f6...",
  "description": "Production webhook",
  "created_at": "2026-01-15T10:00:00Z"
}

Important: The secret is only returned on creation. Store it securely for signature verification.

Get Webhook

GET /api/v1/webhooks/:id

Update Webhook

PUT /api/v1/webhooks/:id

Delete Webhook

DELETE /api/v1/webhooks/:id

Send Test Event

POST /api/v1/webhooks/:id/test

Sends a test event to the webhook endpoint to verify connectivity.

bash
curl -X POST /api/v1/webhooks/wh_abc123/test \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"event_type": "workflow.execution.completed"}'

Delivery History

GET /api/v1/webhooks/:id/executions

Query Parameters:

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
statusstringFilter: delivered, failed, pending

Response:

json
{
  "data": [
    {
      "id": "del_abc123",
      "event_id": "evt_xyz789",
      "event_type": "workflow.execution.completed",
      "status": "delivered",
      "response_code": 200,
      "response_time_ms": 145,
      "attempt": 1,
      "created_at": "2026-01-15T10:30:00Z"
    }
  ],
  "total": 42,
  "page": 1,
  "per_page": 20
}

Incoming Webhooks

Incoming webhooks let external services send data into Arcanflows. Each incoming webhook gets a unique public URL that can trigger workflows or store data.

List Incoming Webhooks

GET /api/v1/incoming-webhooks

Create Incoming Webhook

POST /api/v1/incoming-webhooks

Request Body:

FieldTypeRequiredDescription
namestringYesDisplay name
slugstringNoCustom URL slug (auto-generated if omitted)
workflow_idstringNoWorkflow to trigger on receipt
activebooleanNoEnable immediately (default: true)
bash
curl -X POST /api/v1/incoming-webhooks \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Stripe Payment Events",
    "slug": "stripe-payments",
    "workflow_id": "wf_abc123",
    "active": true
  }'

Response:

json
{
  "id": "iwh_abc123",
  "name": "Stripe Payment Events",
  "slug": "stripe-payments",
  "url": "https://api.arcanflows.io/webhooks/in/stripe-payments",
  "workflow_id": "wf_abc123",
  "active": true,
  "created_at": "2026-01-15T10:00:00Z"
}

Get Incoming Webhook

GET /api/v1/incoming-webhooks/:id

List Received Events

GET /api/v1/incoming-webhooks/:id/events

Returns a log of all payloads received on this incoming webhook.

Receive Webhook (Public Endpoint)

POST /webhooks/in/:slug

This is the public URL that external services POST to. No authentication required. The payload is stored and optionally triggers the linked workflow.

bash
# External service sends data to your incoming webhook
curl -X POST https://api.arcanflows.io/webhooks/in/stripe-payments \
  -H "Content-Type: application/json" \
  -d '{"type": "payment_intent.succeeded", "data": {"amount": 2000}}'

Event Types

Arcanflows uses a structured event type system. Event types are organized by category and define the schema of event payloads.

List All Event Types

GET /api/v1/event-types

Response:

json
{
  "event_types": [
    {
      "name": "agent.chat.completed",
      "category": "agent",
      "description": "Fired when an agent chat conversation ends",
      "schema": { "type": "object", "properties": { ... } }
    },
    {
      "name": "workflow.execution.completed",
      "category": "workflow",
      "description": "Fired when a workflow execution finishes successfully"
    }
  ]
}

Event Categories

GET /api/v1/event-types/categories

Returns grouped categories: agent, workflow, form, approval, data_table, system.

Get Event Type Details

GET /api/v1/event-types/:event_type

Returns full schema and documentation for a specific event type.

Available Events

Agent Events

EventDescription
agent.createdNew agent created
agent.updatedAgent settings changed
agent.deletedAgent deleted
agent.publishedAgent published
agent.chat.startedChat conversation started
agent.chat.messageNew message in conversation
agent.chat.completedChat conversation ended

Workflow Events

EventDescription
workflow.createdNew workflow created
workflow.updatedWorkflow definition changed
workflow.deletedWorkflow deleted
workflow.publishedWorkflow published
workflow.execution.startedWorkflow execution began
workflow.execution.completedWorkflow execution finished
workflow.execution.failedWorkflow execution failed
workflow.execution.node_completedIndividual node completed

Form Events

EventDescription
form.createdNew form created
form.updatedForm configuration changed
form.deletedForm deleted
form.publishedForm published
form.submission.createdNew form submission
form.submission.updatedSubmission updated

Approval Events

EventDescription
approval.requestedApproval request created
approval.approvedRequest approved
approval.rejectedRequest rejected
approval.timeoutRequest timed out

Event Subscriptions

Event subscriptions connect event types to actions (webhook delivery, workflow trigger, notification, etc.).

List Subscriptions

GET /api/v1/event-subscriptions

Create Subscription

POST /api/v1/event-subscriptions

Request Body:

FieldTypeRequiredDescription
event_typestringYesEvent type to subscribe to (e.g., agent.chat.completed)
action_typestringYesAction: webhook, workflow, notification
action_configobjectYesAction-specific configuration
filtersobjectNoFilter conditions for the event
activebooleanNoEnable immediately (default: true)
bash
curl -X POST /api/v1/event-subscriptions \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "form.submission.created",
    "action_type": "workflow",
    "action_config": {
      "workflow_id": "wf_abc123"
    },
    "filters": {
      "form_id": "form_xyz789"
    }
  }'

Get Subscription

GET /api/v1/event-subscriptions/:id

Update Subscription

PUT /api/v1/event-subscriptions/:id

Delete Subscription

DELETE /api/v1/event-subscriptions/:id

Activate Workflow Subscription

POST /api/v1/workflows/:workflow_id/subscriptions/activate

Activates all event subscriptions linked to a workflow.

Deactivate Workflow Subscription

POST /api/v1/workflows/:workflow_id/subscriptions/deactivate

Deactivates all event subscriptions linked to a workflow.


Event Log

The event log provides an audit trail of all events emitted in your tenant.

List Events

GET /api/v1/event-log

Query Parameters:

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
event_typestringFilter by event type
fromstringStart date (ISO 8601)
tostringEnd date (ISO 8601)
correlation_idstringFilter by correlation ID

Response:

json
{
  "data": [
    {
      "id": "evt_abc123",
      "type": "workflow.execution.completed",
      "correlation_id": "corr_xyz789",
      "data": {
        "workflow_id": "wf_abc123",
        "execution_id": "exec_def456",
        "status": "completed"
      },
      "created_at": "2026-01-15T10:30:00Z"
    }
  ],
  "total": 156,
  "page": 1,
  "per_page": 20
}

Get Event

GET /api/v1/event-log/:event_id

Trace Event Chain

GET /api/v1/event-log/trace/:correlation_id

Returns all events sharing the same correlation ID, allowing you to trace a chain of cause-and-effect events (e.g., form submission -> workflow execution -> notification sent).

Emit Test Event

POST /api/v1/events/test

Request Body:

json
{
  "event_type": "workflow.execution.completed",
  "data": {
    "workflow_id": "wf_test",
    "status": "completed"
  }
}

Emits a test event that triggers all matching subscriptions. Useful for testing your event-driven workflows.


Webhook Security

Signature Verification

Every outgoing webhook includes HMAC-SHA256 signature headers:

X-Arcanflows-Signature: sha256=abc123...
X-Arcanflows-Timestamp: 1702469400

Verifying Signatures (Node.js)

javascript
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, timestamp, secret) {
  // Reject if timestamp is older than 5 minutes (replay protection)
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - timestamp) > 300) {
    return false;
  }

  const signedPayload = `${timestamp}.${payload}`;
  const expected = crypto
    .createHmac('sha256', secret)
    .update(signedPayload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(`sha256=${expected}`)
  );
}

Verifying Signatures (Python)

python
import hmac, hashlib, time

def verify_signature(payload: bytes, signature: str, timestamp: str, secret: str) -> bool:
    now = int(time.time())
    if abs(now - int(timestamp)) > 300:
        return False
    signed_payload = f"{timestamp}.{payload.decode()}"
    expected = hmac.new(secret.encode(), signed_payload.encode(), hashlib.sha256).hexdigest()
    return hmac.compare_digest(signature, f"sha256={expected}")

Retry Policy

Failed webhook deliveries are retried with exponential backoff:

AttemptDelayCumulative
1Immediate0
21 minute1 min
35 minutes6 min
430 minutes36 min
52 hours~2.5 hrs
68 hours~10.5 hrs
724 hours~34.5 hrs

After 7 failed attempts the delivery is marked as permanently failed. Retried requests include the header X-Arcanflows-Retry-Count.


Best Practices

  1. Respond quickly -- Return a 200 status immediately, then process the event asynchronously.
  2. Verify signatures -- Always validate the HMAC-SHA256 signature before processing.
  3. Handle duplicates -- Use the event id field for idempotency; the same event may be delivered more than once.
  4. Use event subscriptions -- Prefer event subscriptions over webhooks when you want to trigger workflows automatically.
  5. Monitor delivery logs -- Check /webhooks/:id/executions regularly to catch failures early.
  6. Use correlation IDs -- Trace related events using /event-log/trace/:correlation_id.