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

# Redeliver an event

> Owners and admins only. Sends the same event id and body again with a fresh retry budget and a 72-hour window. Refused with 409 while the delivery is pending or in flight, when the subscription or destination is not active, or when the event is 27 days old or older. Validated before commit. The required Idempotency-Key answers a retry with the first answer for 24 hours instead of sending the event again.



## OpenAPI

````yaml https://api.enrik.ai/v1/openapi.json post /v1/webhook-event-deliveries/{id}/redeliver
openapi: 3.1.2
info:
  title: Enrik API
  version: v1
  description: >-
    The public Enrik API, version 1. It is a server-to-server API: call it from
    your backend, never from a browser. It sends no CORS headers, and an
    `OPTIONS` request to an API path answers `405 method_not_allowed`.
    Authenticate with an API key sent as a Bearer token; each operation lists
    the scopes the key needs, and the `apiKey` security scheme says what each
    scope grants. Operations marked `x-stability-level: beta` may still change;
    `stable` ones change only in a new version. A query parameter or body field
    an operation does not declare is refused with `422 validation_error`, naming
    it. Every error answers the same envelope: branch on the HTTP status and
    `error.code`, whose known values `ErrorInfo` lists.
  contact:
    name: Enrik support
    email: support@enrik.ai
    url: https://docs.enrik.ai
servers:
  - url: https://api.enrik.ai
    description: Production
security: []
tags:
  - name: apiKeys
    description: >-
      API keys. Public, for any authenticated key: `GET /v1/me`, where it reads
      its own id, name, display prefix, expiry, workspace and scopes, and `POST
      /v1/me/rotate` and `POST /v1/me/revoke`, where it rotates its own secret
      or revokes itself. Minting, listing, rotating and revoking other keys is
      internal: an owner or admin does it in Settings → API keys.
  - name: companies
    description: >-
      Companies: the organisations in your workspace, with their contacts,
      timeline and where their facts came from.
  - name: companyCandidates
    description: >-
      Company candidates: companies a discovery job found, or a user added,
      waiting for review. Accept, reject (dismiss), archive and promote them,
      one at a time or in bulk.
  - name: companyDiscoveryJobs
    description: >-
      Company discovery jobs: searches for candidate companies from one source,
      with their candidates and a quality summary. Read-only here; running a job
      stays in the app.
  - name: companySignals
    description: >-
      Company signals: displayed signals about one company, with their evidence.
      Manual writes are internal session operations.
  - name: contacts
    description: 'Contacts: the people in your workspace, with their timeline.'
  - name: customFieldDefinitions
    description: >-
      Custom fields: the fields a workspace added to its contacts and companies,
      which their `customFields` hold by key.
  - name: discoveryBriefs
    description: >-
      Discovery briefs: how to find and judge companies for one ICP profile
      version, and their immutable versions. Read-only here.
  - name: exportFields
    description: >-
      The fields an export can carry, the workspace’s custom and recommendation
      fields included.
  - name: exportJobs
    description: >-
      CSV exports of companies, contacts and candidates: create a draft, preview
      it, start it, poll it and download the file. A key reads them with
      `exports:read` and runs them with `exports:run` and `crm:read`; delivery
      to a webhook destination stays in the app.
  - name: feedback
    description: >-
      Anonymous agent feedback about the public API. Any authenticated API key
      may send a note, which is stored with no sender; the report is an internal
      operator read.
  - name: health
    description: >-
      Whether the API is up: `GET /v1/health`, public and needing no API key, is
      the API catalog’s `status` link. The liveness and readiness probes for
      load balancers stay internal.
  - name: icpAssessments
    description: >-
      ICP assessments: how one company fares against an ICP profile version, as
      stored. Reading never evaluates.
  - name: icpProfiles
    description: >-
      ICP profiles: ideal customer profiles and the immutable versions that hold
      their criteria. Read-only here.
  - name: savedViews
    description: >-
      Saved views: named sets of filters, sort and columns over contacts or
      companies, which replay to the same records as the equivalent list query.
  - name: signalDefinitions
    description: >-
      Signal definitions: the signals the workspace looks for in companies, and
      the immutable versions that say what they are. Read-only here.
  - name: signalDetectors
    description: >-
      Signal detectors: the kinds of detector a signal definition can use, and
      why any cannot run.
  - name: webhookEventDeliveries
    description: 'The delivery log of webhook events: states and attempts, never a body.'
  - name: webhookEventTypes
    description: >-
      The webhook event types a subscription can name, and the permission and
      key scope each needs.
  - name: webhookSubscriptions
    description: >-
      Webhook subscriptions: which events Enrik sends, signed, to a receiver
      URL; edit, test, pause, resume and archive them, and rotate their signing
      secret. Owners and admins manage them, and grant `webhooks:write` to a
      key.
  - name: websiteOnboarding
    description: >-
      Workspace company setup: shared profile confirmation and durable command
      receipts. Public scoped setup operations and internal handoff/artifact
      projections.
  - name: workspaceMembers
    description: >-
      Workspace members: the people who use the workspace, as the user id and
      name a contact’s or company’s `ownerUserId` takes. Read-only.
externalDocs:
  description: Guides, authentication, errors, scopes and pagination.
  url: https://docs.enrik.ai
paths:
  /v1/webhook-event-deliveries/{id}/redeliver:
    post:
      tags:
        - webhookEventDeliveries
      summary: Redeliver an event
      description: >-
        Owners and admins only. Sends the same event id and body again with a
        fresh retry budget and a 72-hour window. Refused with 409 while the
        delivery is pending or in flight, when the subscription or destination
        is not active, or when the event is 27 days old or older. Validated
        before commit. The required Idempotency-Key answers a retry with the
        first answer for 24 hours instead of sending the event again.
      operationId: webhookEventDeliveries.redeliver
      parameters:
        - name: id
          in: path
          required: true
          description: The event delivery’s id.
          schema:
            type: string
            format: uuid
            pattern: >-
              ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: >-
            One event on its way to one subscription: state and last outcome,
            never a body.
          headers:
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimitPolicy'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookEventDelivery'
              example:
                id: 0199a1b2-0000-7000-8000-000000000538
                subscriptionId: 0199a1b2-0000-7000-8000-000000000538
                eventId: 0199a1b2-0000-7000-8000-00000000a538
                eventType: companyDiscoveryJob.terminal
                state: pending
                attemptCount: 1
                nextAttemptAt: '2026-10-07T08:00:00.000Z'
                expiresAt: '2026-10-10T08:00:00.000Z'
                lastAttemptAt: '2026-10-07T08:00:00.000Z'
                lastResponseStatus: 204
                lastErrorCode: null
                deliveredAt: null
                createdAt: '2026-10-07T08:00:00.000Z'
                updatedAt: '2026-10-07T08:00:00.000Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableContent'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
        default:
          $ref: '#/components/responses/Error'
      security:
        - apiKey:
            - webhooks:write
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: >-
        A key you choose for this request, such as a UUID. Retrying with the
        same key returns the first result instead of doing the work twice.
      schema:
        type: string
        minLength: 1
        maxLength: 200
  headers:
    RateLimit:
      description: >-
        What the API key has left under each rate-limit policy that counted this
        request: a Structured Field list with one
        `"<policy>";r=<remaining>;t=<seconds>` item per policy. Read it as a
        list and honour every item, not only the smallest: continued traffic
        must satisfy each policy. `t` is the effective window in seconds (IETF
        RateLimit header fields, draft 11): quota is not guaranteed to be fully
        restored when it ends. When the answer also carries `Retry-After`, that
        takes priority. One policy counts this operation: `api-key`, every
        request the key makes.
      schema:
        type: string
      example: '"api-key";r=599;t=60'
    RateLimitPolicy:
      description: >-
        The rate-limit policies that counted this request: a Structured Field
        list with one `"<policy>";q=<requests>;w=<window in seconds>` item per
        policy. The limits belong to the key, not to the address it calls from.
        One policy counts this operation: `api-key`, every request the key
        makes.
      schema:
        type: string
      example: '"api-key";q=600;w=60'
    RetryAfter:
      description: >-
        Seconds to wait before retrying. It takes priority over the `t` of every
        `RateLimit` item.
      schema:
        type: integer
        minimum: 1
      example: 60
  schemas:
    WebhookEventDelivery:
      type: object
      properties:
        id:
          type: string
          description: The delivery id, also sent as `X-Enrik-Delivery-Id`.
        subscriptionId:
          type: string
          description: The subscription the event is delivered to.
        eventId:
          type: string
          description: >-
            The event id, also sent as `X-Enrik-Event-Id`; the same on every
            attempt.
        eventType:
          type: string
          enum:
            - companyDiscoveryJob.terminal
            - company.created
            - company.updated
            - company.deleted
            - company.restored
            - contact.created
            - contact.updated
            - contact.deleted
            - contact.restored
            - companySignal.created
          description: The event type.
        state:
          type: string
          enum:
            - pending
            - delivering
            - delivered
            - failed
            - canceled
            - expired
          description: >-
            Where the delivery is: pending or in flight, or ended (delivered,
            failed, canceled, expired).
        attemptCount:
          type: number
          description: HTTP attempts so far, redeliveries included.
        nextAttemptAt:
          anyOf:
            - type: string
              format: date-time
              pattern: >-
                ^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$
            - type: 'null'
          description: When the next attempt is due; `null` once the delivery ended.
        expiresAt:
          type: string
          format: date-time
          pattern: >-
            ^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$
          description: When the delivery stops being attempted.
        lastAttemptAt:
          anyOf:
            - type: string
              format: date-time
              pattern: >-
                ^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$
            - type: 'null'
          description: When the last attempt started, if any.
        lastResponseStatus:
          description: >-
            The HTTP status the receiver last answered; `null` without an
            answer.
          type:
            - number
            - 'null'
        lastErrorCode:
          anyOf:
            - type: string
              enum:
                - http_status
                - timeout
                - network_error
                - egress_blocked
                - redirect_blocked
                - response_too_large
                - retries_exhausted
                - subscription_inactive
                - destination_inactive
                - signing_secret_missing
                - workspace_deleted
            - type: 'null'
          description: >-
            Why the last attempt failed; `null` when it succeeded or none was
            made.
        deliveredAt:
          anyOf:
            - type: string
              format: date-time
              pattern: >-
                ^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$
            - type: 'null'
          description: When the receiver accepted it, if it did.
        createdAt:
          type: string
          format: date-time
          pattern: >-
            ^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$
          description: When the delivery was created.
        updatedAt:
          type: string
          format: date-time
          pattern: >-
            ^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$
          description: When it last changed.
      required:
        - id
        - subscriptionId
        - eventId
        - eventType
        - state
        - attemptCount
        - nextAttemptAt
        - expiresAt
        - lastAttemptAt
        - lastResponseStatus
        - lastErrorCode
        - deliveredAt
        - createdAt
        - updatedAt
      additionalProperties: true
      description: >-
        One event on its way to one subscription: state and last outcome, never
        a body.
    ErrorEnvelope:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/ErrorInfo'
          description: >-
            What went wrong: the code to branch on, a message and the request
            id.
      required:
        - error
      additionalProperties: true
      description: The body of every error response.
    ErrorInfo:
      type: object
      properties:
        code:
          type: string
          x-extensible-enum:
            - malformed_json
            - invalid_sort
            - unauthenticated
            - insufficient_scope
            - permission_denied
            - beta_access_required
            - not_a_member
            - not_found
            - method_not_allowed
            - conflict
            - stale_version
            - idempotency_key_reused
            - request_in_flight
            - company_twin_research_already_running
            - company_twin_own_domain_conflict
            - concurrent_run_limit
            - gone
            - payload_too_large
            - unsupported_media_type
            - validation_error
            - rate_limited
            - internal_error
            - response_contract_violation
            - service_unavailable
          description: >-
            A stable, machine-readable code such as `not_found`. Branch on this,
            not on `message`. The known values are every code a public operation
            answers; more may be added, so handle an unknown one by its HTTP
            status.
        message:
          type: string
          description: A human-readable explanation. It may change; do not parse it.
        requestId:
          type: string
          description: >-
            The id of the request that failed. Quote it when you contact
            support.
        details:
          description: >-
            Structured detail for some codes. For `validation_error` it is
            usually an array with one entry per problem: `path` (the field,
            dotted), `message` and, where the case has a name, `code` (such as
            `related_record_not_found`). Other codes that cover several cases
            carry an object whose `code` names the case (such as
            `invalid_cursor`).
      required:
        - code
        - message
        - requestId
      additionalProperties: true
      description: What went wrong.
  responses:
    BadRequest:
      description: >-
        The request could not be read. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `malformed_json`: The body is not valid JSON, or is empty while
        `Content-Type` is `application/json`. Send valid JSON; omit
        `Content-Type` when there is no body.

        - `invalid_sort`: A sort names a field or direction the list does not
        support. Sort only by the fields the operation lists.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: malformed_json
              message: Bad Request
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    Unauthorized:
      description: >-
        The request is not authenticated. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `unauthenticated`: The key is missing, invalid, expired or revoked.
        Send a valid, unexpired key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: unauthenticated
              message: Unauthorized
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    Forbidden:
      description: >-
        The caller may not do this. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `insufficient_scope`: The key lacks a scope the operation, or a
        parameter such as `include` or `rankingMode`, needs.
        `details.missingScopes` names it; `WWW-Authenticate` lists every scope
        the request needs. Create a key with the missing scope.

        - `permission_denied`: The key’s scopes admit the operation, but its
        permissions do not cover this request: replaying a create needs
        `crm:read`, and a key keeps the permissions its scopes had when it was
        created. The message names the scope. Create a new key with the scope
        the message names.

        - `beta_access_required`: The workspace is not admitted to the beta,
        which every write except `feedback.submit` needs. Contact support.

        - `not_a_member`: `websiteOnboarding.getAccess`: the key’s workspace has
        been deleted. Use a key of a live workspace.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: insufficient_scope
              message: Forbidden
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    NotFound:
      description: >-
        Nothing was found. Branch on `error.code`; quote `error.requestId` to
        support.


        The codes a public operation answers with it:


        - `not_found`: No such record in your workspace. A path that is not part
        of the public API also answers `404`. Check the id and the path.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: not_found
              message: Not Found
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    Conflict:
      description: >-
        The request conflicts with the current state. Branch on `error.code`;
        quote `error.requestId` to support.


        The codes a public operation answers with it:


        - `conflict`: The request clashes with the current state, such as a
        duplicate domain or e-mail, a changed setup or a ranked list that
        changed. `details.code` names the case where there is one. Read fresh
        state, then decide.

        - `stale_version`: The record changed since the `expectedUpdatedAt` you
        sent. `details.currentUpdatedAt` is its current version. Read the record
        again and reapply your change.

        - `idempotency_key_reused`: The `Idempotency-Key` was used for a
        different command or body. Use a new key for a new command.

        - `request_in_flight`: The first request with this `Idempotency-Key` is
        still running. Retry shortly with the same key.

        - `company_twin_research_already_running`:
        `websiteOnboarding.confirmProfile`: research for this setup or website
        is already running. Read fresh setup state.

        - `company_twin_own_domain_conflict`:
        `websiteOnboarding.confirmProfile`: the website does not match the
        workspace’s company profile. Read fresh setup state, then confirm the
        profile with its own website.

        - `concurrent_run_limit`: `companyDiscoveryJobs.start` by an API key:
        the workspace already has as many discovery jobs queued or running as a
        key may start beside. `details.code` names the cap. Wait for a job to
        finish, or cancel one, then start again.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: conflict
              message: Conflict
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    UnprocessableContent:
      description: >-
        The request cannot be used as sent. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `validation_error`: The request does not match the operation’s schema,
        a field names something that does not exist, or a value cannot be used,
        such as an id that is not a UUID, a date outside the years 0001–9999 in
        a filter, or an edited cursor. See `details`. Fix the request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: validation_error
              message: Unprocessable Entity
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    RateLimited:
      description: >-
        Too many requests (`error.code` is `rate_limited`): the API key spent a
        rate-limit policy, or the network it calls from presented too many
        invalid keys. Wait `Retry-After` seconds before retrying; it takes
        priority over `RateLimit`.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
        RateLimit:
          $ref: '#/components/headers/RateLimit'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimitPolicy'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: rate_limited
              message: Too many requests
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    InternalServerError:
      description: >-
        The request failed on the server. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `internal_error`: Something failed on our side. Retry later; reuse a
        command’s idempotency key.

        - `response_contract_violation`: Our answer broke its own schema, so it
        was withheld. `details.committed` says whether a change was saved. If
        `committed` is true, read the state instead of resending. Quote the
        request id.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: internal_error
              message: Internal Server Error
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    ServiceUnavailable:
      description: >-
        The service is briefly unavailable. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `service_unavailable`: A create ran out of time, or the service is
        briefly unavailable. Retry later with the same idempotency key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: service_unavailable
              message: Service Unavailable
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    Error:
      description: >-
        The request failed. Branch on `error.code`; quote `error.requestId` to
        support.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: not_found
              message: Not found
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        An Enrik API key, sent as `Authorization: Bearer <key>`. A key reaches
        public operations only, and only those whose scopes it holds. A few
        parameters need a scope beyond their operation’s, which the parameter
        names. The scopes:


        - `setup:read`: Read the workspace setup and its company profile.

        - `setup:run`: Change the setup: confirm the company profile, authorize
        sponsored drafting and background company research, choose what to set
        up and complete setup.

        - `workspace:read`: Read the workspace’s own profile: its health summary
        and setup state.

        - `crm:read`: Read companies with their signals, contacts and the saved
        views over them.

        - `crm:write`: Create, update and restore companies and contacts, and
        create, update and delete saved views.

        - `crm:delete`: Delete companies and contacts.

        - `twin:read`: Read the Company Twin: structured company knowledge and
        its signals.

        - `discovery:read`: Read ICP profiles, ICP assessments, discovery
        briefs, discovery jobs, candidates and the signal library.

        - `discovery:write`: Create and change ICP profiles, discovery briefs
        and signal-definition drafts, and review discovery candidates.

        - `discovery:run`: Create, start and cancel discovery jobs, and edit a
        draft one. Uses provider budget.

        - `enrichment:read`: Read the enrichment configuration and its results,
        including a record’s enrichment, formula and custom-API cells.

        - `enrichment:run`: Launch and cancel enrichment. Spends enrichment
        credits.

        - `automation:read`: Read workflows and agents with their run history,
        including a record’s agent cells.

        - `automation:run`: Run existing workflows and agents.

        - `exports:read`: Read export jobs and the fields an export can carry.

        - `exports:run`: Create, preview, start, cancel and archive CSV exports
        of companies, contacts and candidates, and download the file. Also needs
        `crm:read`. Delivering an export to a webhook destination stays in the
        app.

        - `integrations:read`: Read connections, field mappings, CRM sync jobs
        and webhook destinations.

        - `webhooks:read`: Read webhook subscriptions, the event types they can
        name and their delivery log.

        - `webhooks:write`: Subscribe a receiver URL to webhook events; edit,
        test, pause, resume and archive a subscription and rotate its signing
        secret; redeliver an event. Only workspace owners and admins can grant
        it.

        - `reporting:read`: Read analytics and dashboards.

        - `assistant:read`: Read the Assistant: its threads, messages and
        pending approvals.

        - `assistant:run`: Converse with the Assistant. Uses the workspace’s AI
        quota.

        - `assistant:write`: Approve or reject the changes the Assistant
        proposes.

````

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