Ashby · Arazzo Workflow

Ashby Register and Manage a Webhook Subscription

Version 1.0.0

Confirm the API key's access, register a webhook, verify it, then enable or rotate it.

1 workflow 1 source API 1 provider
View Spec View on GitHub ATSApplicant Tracking SystemRecruitingTalent AcquisitionSourcingCRMSchedulingAnalyticsHiringHR TechAIArazzoWorkflows

Provider

ashby-hq

Workflows

webhook-lifecycle
Check API key access, create a webhook, read it back, and update it.
Reads the API key's own metadata to confirm access, creates a webhook subscription for an event type, verifies the registration, and updates the subscription's url, secret, or enabled state.
4 steps inputs: enabled, requestUrl, secretToken, updatedRequestUrl, webhookType outputs: apiKeyScopes, enabled, requestUrl, webhookId, webhookType
1
checkApiKey
apiKeyInfo
Read the API key's own metadata first. This returns the key's permission scopes, which is the cheapest way to confirm the credential can actually write webhook settings before creating a subscription that would otherwise fail halfway through setup.
2
createWebhook
webhookcreate
Register the webhook for the chosen event type. The secretToken supplied here is what Ashby uses to sign every delivery, so it must be stored by the receiver, not discarded.
3
readWebhook
webhookInfo
Read the subscription back to confirm it registered against the intended url and event type.
4
updateWebhook
webhookupdate
Update the subscription. This same call rotates the secret token, moves the delivery url, and disables a subscription without deleting it — the safe way to pause deliveries during receiver maintenance. webhook.delete removes it permanently and is deliberately not part of this flow.

Source API Descriptions

Arazzo Workflow Specification

Raw ↑
arazzo: 1.0.1
info:
  title: Ashby Register and Manage a Webhook Subscription
  summary: Confirm the API key's access, register a webhook, verify it, then enable or rotate it.
  description: >-
    Every event-driven Ashby integration starts here. The flow confirms what the
    API key can actually do before writing anything, registers a webhook for a
    chosen event type with a secret token, reads the registration back, and then
    updates it — the same call used to rotate the secret or disable a noisy
    subscription. The secret token matters: Ashby signs each delivery with it as
    an HMAC-SHA256 in the Ashby-Signature header, and a receiver that skips that
    check will accept forged events. Every step spells out its request inline so
    the flow can be read and executed without opening the underlying OpenAPI
    description.
  version: 1.0.0
sourceDescriptions:
- name: ashbyApi
  url: ../openapi/ashby-openapi.yml
  type: openapi
workflows:
- workflowId: webhook-lifecycle
  summary: Check API key access, create a webhook, read it back, and update it.
  description: >-
    Reads the API key's own metadata to confirm access, creates a webhook
    subscription for an event type, verifies the registration, and updates the
    subscription's url, secret, or enabled state.
  inputs:
    type: object
    required:
    - webhookType
    - requestUrl
    - secretToken
    properties:
      webhookType:
        type: string
        description: >-
          The event type to subscribe to (e.g. applicationSubmit,
          candidateStageChange, offerCreate, jobPostingPublish).
      requestUrl:
        type: string
        description: The https endpoint Ashby should POST events to.
      secretToken:
        type: string
        description: >-
          The shared secret Ashby signs deliveries with. The receiver must verify
          the Ashby-Signature HMAC-SHA256 header against this value.
      updatedRequestUrl:
        type: string
        description: A new delivery url, when moving or rotating the endpoint.
      enabled:
        type: boolean
        description: Whether the subscription should remain enabled.
  steps:
  - stepId: checkApiKey
    description: >-
      Read the API key's own metadata first. This returns the key's permission
      scopes, which is the cheapest way to confirm the credential can actually
      write webhook settings before creating a subscription that would otherwise
      fail halfway through setup.
    operationId: apiKeyInfo
    requestBody:
      contentType: application/json
      payload: {}
    successCriteria:
    - condition: $statusCode == 200
    - condition: $response.body#/success == true
    outputs:
      apiKeyTitle: $response.body#/results/title
      apiKeyScopes: $response.body#/results/scopes
  - stepId: createWebhook
    description: >-
      Register the webhook for the chosen event type. The secretToken supplied
      here is what Ashby uses to sign every delivery, so it must be stored by the
      receiver, not discarded.
    operationId: webhookcreate
    requestBody:
      contentType: application/json
      payload:
        webhookType: $inputs.webhookType
        requestUrl: $inputs.requestUrl
        secretToken: $inputs.secretToken
    successCriteria:
    - condition: $statusCode == 200
    - condition: $response.body#/success == true
    outputs:
      webhookId: $response.body#/results/id
      webhookType: $response.body#/results/webhookType
      enabled: $response.body#/results/enabled
  - stepId: readWebhook
    description: >-
      Read the subscription back to confirm it registered against the intended
      url and event type.
    operationId: webhookInfo
    requestBody:
      contentType: application/json
      payload:
        webhookId: $steps.createWebhook.outputs.webhookId
    successCriteria:
    - condition: $statusCode == 200
    - condition: $response.body#/success == true
    outputs:
      webhookId: $response.body#/results/id
      requestUrl: $response.body#/results/requestUrl
      enabled: $response.body#/results/enabled
  - stepId: updateWebhook
    description: >-
      Update the subscription. This same call rotates the secret token, moves the
      delivery url, and disables a subscription without deleting it — the safe
      way to pause deliveries during receiver maintenance. webhook.delete removes
      it permanently and is deliberately not part of this flow.
    operationId: webhookupdate
    requestBody:
      contentType: application/json
      payload:
        webhookId: $steps.createWebhook.outputs.webhookId
        requestUrl: $inputs.updatedRequestUrl
        enabled: $inputs.enabled
    successCriteria:
    - condition: $statusCode == 200
    - condition: $response.body#/success == true
    outputs:
      webhookId: $response.body#/results/id
      requestUrl: $response.body#/results/requestUrl
      enabled: $response.body#/results/enabled
  outputs:
    apiKeyScopes: $steps.checkApiKey.outputs.apiKeyScopes
    webhookId: $steps.createWebhook.outputs.webhookId
    webhookType: $steps.createWebhook.outputs.webhookType
    requestUrl: $steps.updateWebhook.outputs.requestUrl
    enabled: $steps.updateWebhook.outputs.enabled