> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cyberdesk.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook Transformations

> Transform webhook payloads before delivery to your endpoint

Webhook transformations let you modify the payload before it's delivered to your endpoint. This is useful for:

* **Reducing payload size** — Remove fields your endpoint does not need
* **Reshaping the schema** — Transform the data structure to match what your system expects
* **Filtering data** — Remove fields you don't need

<Info>
  Transformations run server-side before the webhook is sent, so your endpoint receives exactly what you want.
</Info>

## Enabling Transformations

<Steps>
  <Step title="Open the Webhooks portal">
    Navigate to the **Webhooks** tab in your Cyberdesk dashboard.
  </Step>

  <Step title="Select your endpoint">
    Click on the **Endpoints** tab and select the endpoint you want to transform.
  </Step>

  <Step title="Open Advanced settings">
    Click on the **Advanced** sub-tab within the endpoint details.
  </Step>

  <Step title="Enable transformations">
    Toggle **Enable Transformation** to on.
  </Step>

  <Step title="Edit your transformation">
    Click **Edit Transformation** next to the toggle to open the transformation editor.
  </Step>

  <Step title="Write and test your code">
    Write your JavaScript transformation function, then use the **Test** feature to verify it works with sample payloads.
  </Step>
</Steps>

## Writing a Transformation

Transformations are JavaScript functions that receive the webhook data and return a modified version. The function must be named `handler` and receives an object with these properties:

| Property                | Description                                                |
| ----------------------- | ---------------------------------------------------------- |
| `payload`               | The webhook payload (JSON object) — modify as needed       |
| `method`                | HTTP method (`"POST"` or `"PUT"`) — can be changed         |
| `url`                   | Endpoint URL — can be changed to redirect                  |
| `eventType`             | Event type string (changes ignored)                        |
| `transformationsParams` | Object passed via the create-message API (changes ignored) |

The function must return the same object, but may modify its properties as described above. You can also set these additional properties on the returned object:

| Property  | Description                                                            |
| --------- | ---------------------------------------------------------------------- |
| `cancel`  | Boolean to cancel dispatch (defaults to `false`)                       |
| `headers` | Object of HTTP headers to add (takes precedence over endpoint headers) |

### Example: Remove Output Data

If your endpoint only needs run status and metadata, remove `output_data` to reduce payload size:

```javascript theme={null}
function handler(webhook) {
  if (webhook.payload.run && webhook.payload.run.output_data) {
    delete webhook.payload.run.output_data;
  }
  return webhook;
}
```

### Example: Extract Only What You Need

Keep just the essential fields for your downstream system:

```javascript theme={null}
function handler(webhook) {
  const run = webhook.payload.run;
  
  // Replace payload with only the fields you need
  webhook.payload = {
    event_type: webhook.payload.event_type,
    run_id: run.id,
    status: run.status,
    output_data: run.output_data,
    workflow_id: run.workflow_id,
    completed_at: run.ended_at
  };
  
  return webhook;
}
```

### Example: Cancel Webhooks Conditionally

You can cancel delivery for certain events:

```javascript theme={null}
function handler(webhook) {
  // Don't send webhooks for cancelled runs
  if (webhook.payload.run?.status === "cancelled") {
    webhook.cancel = true;
  }
  return webhook;
}
```

<Note>
  Cancelled messages appear as successful dispatches in the logs but are not actually sent to your endpoint.
</Note>

### Example: Add Custom Headers

Add headers for routing or authentication on your end:

```javascript theme={null}
function handler(webhook) {
  webhook.headers = {
    "X-Workflow-Id": webhook.payload.run?.workflow_id || "",
    "X-Run-Status": webhook.payload.run?.status || ""
  };
  return webhook;
}
```

## Testing Your Transformation

The transformation editor includes a test panel where you can:

1. Select an event type to get a sample payload
2. Or paste a custom payload
3. Run your transformation
4. See the resulting webhook that would be sent

Always test your transformation before saving to ensure it produces the expected output.

## Common Issues

<AccordionGroup>
  <Accordion title="Transformation not running">
    Make sure the **Enable Transformation** toggle is on. The toggle and edit button are on the same line in the Advanced tab.
  </Accordion>

  <Accordion title="Payload unchanged after transformation">
    Verify you're returning the modified `webhook` object from your `handler` function. If you forget to return, the original payload is sent.

    ```javascript theme={null}
    // ❌ Wrong - no return
    function handler(webhook) {
      delete webhook.payload.run.output_data;
    }

    // ✅ Correct - returns modified webhook
    function handler(webhook) {
      delete webhook.payload.run.output_data;
      return webhook;
    }
    ```
  </Accordion>

  <Accordion title="JavaScript errors in transformation">
    Check the browser console for syntax errors. Common issues:

    * Missing semicolons or brackets
    * Accessing properties on undefined (use optional chaining: `webhook.payload.run?.status`)
    * Invalid JSON in test payloads
  </Accordion>

  <Accordion title="Webhook delivery failing after adding transformation">
    Your transformation might be throwing an error. Wrap risky operations in try/catch:

    ```javascript theme={null}
    function handler(webhook) {
      try {
        if (webhook.payload.run) {
          delete webhook.payload.run.output_data;
        }
      } catch (e) {
        // Log error but don't break delivery
        console.error("Transformation error:", e);
      }
      return webhook;
    }
    ```
  </Accordion>

  <Accordion title="Large payloads still timing out">
    The default `run_complete` payload omits `run_message_history`. If your payloads are still too large, remove other large fields such as `output_data` or create a minimal payload with only the fields you need.
  </Accordion>
</AccordionGroup>

## Learn More

For detailed documentation on writing transformations, including advanced patterns and the complete API reference, see the [Svix Transformations documentation](https://docs.svix.com/transformations#how-to-write-a-transformation).
