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

# Implementing Events

> Define the events your connector emits in its YAML, so StackOne can normalize and deliver them.

Events let your connector turn a provider's webhooks into normalized StackOne events. As a connector author, you declare the events in the connector YAML; StackOne handles subscription, signature verification, and delivery to a [webhook](/connect/webhooks).

This is the **producing** side. For how a consumer subscribes and receives events, see [Webhook Events](/connect/webhooks); for the concept, see [Events](/gateway/concepts/events).

## Where events live

Event handlers go in a `{provider}.events.s1.partial.yaml` partial, referenced from the connector's `events` block rather than the top-level `actions`. See [File structure](/connector-yaml-reference/file-structure) for the layout.

## The events block

The `events` block has four parts, from provisioning a receiver to handling a delivery:

1. `setup` runs the webhook receiver lifecycle with the provider (create, activate, and delete the receiver).
2. `externalAccountIdExtractor` resolves which linked account an incoming event belongs to.
3. `router` maps each incoming payload to an event action.
4. `actions[]` hold the `actionType: event` handlers that process the matched event.

## Anatomy of an event

Each event is an action with `actionType: event`. It names the provider's native events, maps the incoming webhook payload to its `inputs`, and emits a normalized event with the `emit_event` step function:

```yaml theme={null}
# {provider}.events.s1.partial.yaml
- actionId: webhook_employee_created
  categories:
    - hris
  actionType: event
  label: Employee Created
  description: Processes employee.created events fired when a new employee is added.
  providerEvents:
    - employee.created          # the provider's native event name(s)
  inputs:                       # shape of the incoming webhook payload
    - name: type
      type: string
      in: body
    - name: triggeredAt
      type: string
      in: body
    - name: data
      type: object
      in: body
      properties:
        - name: employeeId
          type: string
  steps:
    - stepId: emit
      description: Emit the normalized event to the StackOne dispatcher.
      stepFunction:
        functionName: emit_event
        parameters:
          event:
            eventId: $.inputs.data.employeeId
            eventType: $.inputs.type
            eventDate: $.inputs.triggeredAt
            data: $.inputs.data
  result:
    statusCode: 200             # acknowledge receipt to the provider
    body:
      status: OK
```

| Field | Purpose |
| - | - |
| `actionType: event` | Marks the action as an inbound event handler, not an API call. |
| `providerEvents` | The provider's native event names this handler accepts. |
| `inputs` | The fields of the incoming webhook payload. |
| `emit_event` step | Maps the payload to a normalized event (`eventId`, `eventType`, `eventDate`, `data`). |
| `result` | The `200` acknowledgement returned to the provider. |

## Registering the receiver

When the provider has a webhook API, provision the receiver programmatically in the `events.setup` block. StackOne runs its phases against the provider: `creation` (required) when events are enabled on a Connector Profile, `deletion` (required) when they are removed, and an optional `activation` step in between. Each phase is a list of ordinary `request` steps.

StackOne threads two values through these steps:

* `${inputs.callbackUrl}` — the StackOne receiver URL the provider should post events to. Map it into the create request.
* `${inputs.remoteId}` — the id of the webhook the provider created, read from `creation.result`. `activation` and `deletion` reference it to target that webhook.

```yaml theme={null}
# {provider}.connector.s1.yaml
events:
  setup:
    creation:
      steps:
        - stepId: create_webhook
          stepFunction:
            functionName: request
            parameters:
              url: /webhooks
              method: post
              args:
                - { name: url, value: '${inputs.callbackUrl}', in: body }
      result: $.steps.create_webhook.output.data.id   # StackOne stores this as ${inputs.remoteId}
    deletion:
      steps:
        - stepId: delete_webhook
          stepFunction:
            functionName: request
            parameters:
              url: '/webhooks/${inputs.remoteId}'
              method: delete
```

If the provider has no webhook API, leave `setup` out and register manually with a [Native Webhook URL](#native-webhook-url).

## Native Webhook URL

When a provider is configured manually, expose a Native Webhook URL on the connector profile by adding a field to your authentication config:

```yaml theme={null}
- key: nativeWebhookUrl
  label: Native Webhook URL
  value: "{{webhookEventsUrl(webhooks_url, orgId, projectSecureId, connectorProfileId, external_trigger_token)}}"
  description: Paste this into the provider's webhook settings.
```

The user copies this URL into the provider's own webhook configuration, guided by the steps you define in `events.guides.setup`.

## Related

<CardGroup cols={2}>
  <Card title="Events reference" icon="gear" href="/connector-yaml-reference/yaml-schema/events">
    Every field of the events block, with examples.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.