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

# Complete Slack connection

> Requires the initiating user’s Clerk session with the same active organization. Current membership, MFA, owner permission and initiating API-key authority are rechecked explicitly. State must match the initiating browser session and nonce. Slack codes are single-use; failed, repeated or expired completion requires a new attempt. No pending authorization or completion result is stored.



## OpenAPI

````yaml /openapi-preview.json post /v1/notifications/channels/slack/complete
openapi: 3.1.0
info:
  title: Watchdog API (preview)
  version: 1.0.0
  description: >-
    Development preview for agreements, price items, document relationships,
    canonical invoices, alerts and alert topics, claims and attached alerts,
    shared entity activity and comments, Document uploads, invoice imports,
    explicit invoice-agreement matching, and workflow runs. This contract is
    under development and is not served by api.watchdog.no. Request bodies are
    limited to 2 MiB (2,097,152 bytes), including all JSON fields and line data,
    except POST /v1/support/contact which permits 32 MiB for base64 attachments.
    File bytes are uploaded directly to storage. The existing public REST
    service retains its separate contract.
servers:
  - url: http://localhost:3500
    description: Local development Worker
security: []
paths:
  /v1/notifications/channels/slack/complete:
    post:
      tags:
        - Notifications
      summary: Complete Slack connection
      description: >-
        Requires the initiating user’s Clerk session with the same active
        organization. Current membership, MFA, owner permission and initiating
        API-key authority are rechecked explicitly. State must match the
        initiating browser session and nonce. Slack codes are single-use;
        failed, repeated or expired completion requires a new attempt. No
        pending authorization or completion result is stored.
      operationId: completeNotificationSlack
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                state:
                  type: string
                  minLength: 1
                  maxLength: 4096
                code:
                  type: string
                  minLength: 1
                  maxLength: 2048
                browser_nonce:
                  type: string
                  pattern: ^[a-f0-9]{64}$
              required:
                - state
                - code
                - browser_nonce
              additionalProperties: false
      responses:
        '200':
          description: >-
            Notification destination and connection. Delivery settings are in
            preferences; credentials are never returned.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request identifier for support and diagnostics; also included in
                error bodies.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
              required: false
              description: >-
                Organization-scoped API responses must not be cached. May be
                absent for requests rejected before routing.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '120'
              required: false
              description: >-
                Requests per minute for the applicable limiter, when evaluated.
                Authenticated requests use the credential limit; an IP rejection
                uses the IP limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationChannel'
        '400':
          description: >-
            Invalid request format, parameters, or body. Details contain up to
            20 actionable field errors; the complete encoded request body must
            be at most 2 MiB (2,097,152 bytes).
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request identifier for support and diagnostics; also included in
                error bodies.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
              required: false
              description: >-
                Organization-scoped API responses must not be cached. May be
                absent for requests rejected before routing.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '120'
              required: false
              description: >-
                Requests per minute for the applicable limiter, when evaluated.
                Authenticated requests use the credential limit; an IP rejection
                uses the IP limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_validation_error'
              example:
                error:
                  code: validation_error
                  message: >-
                    Invalid request format, parameters, or body. Details contain
                    up to 20 actionable field errors; the complete encoded
                    request body must be at most 2 MiB (2,097,152 bytes).
                  request_id: req_example
        '401':
          description: Missing or invalid bearer credential.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request identifier for support and diagnostics; also included in
                error bodies.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
              required: false
              description: >-
                Organization-scoped API responses must not be cached. May be
                absent for requests rejected before routing.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '120'
              required: false
              description: >-
                Requests per minute for the applicable limiter, when evaluated.
                Authenticated requests use the credential limit; an IP rejection
                uses the IP limit.
            WWW-Authenticate:
              schema:
                type: string
              required: false
              description: Bearer authentication challenge, when supplied.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_invalid_token'
              example:
                error:
                  code: invalid_token
                  message: Missing or invalid bearer credential.
                  request_id: req_example
        '403':
          description: >-
            Access denied: forbidden, token_disabled, organization_required,
            insufficient_role, or mfa_required. Check the error code and
            effective permissions.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request identifier for support and diagnostics; also included in
                error bodies.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
              required: false
              description: >-
                Organization-scoped API responses must not be cached. May be
                absent for requests rejected before routing.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '120'
              required: false
              description: >-
                Requests per minute for the applicable limiter, when evaluated.
                Authenticated requests use the credential limit; an IP rejection
                uses the IP limit.
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/Error_forbidden_token_disabled_organization_required_insufficient_role_mfa_required
              example:
                error:
                  code: forbidden
                  message: >-
                    Access denied: forbidden, token_disabled,
                    organization_required, insufficient_role, or mfa_required.
                    Check the error code and effective permissions.
                  request_id: req_example
        '404':
          description: The resource does not exist in the current organization.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request identifier for support and diagnostics; also included in
                error bodies.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
              required: false
              description: >-
                Organization-scoped API responses must not be cached. May be
                absent for requests rejected before routing.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '120'
              required: false
              description: >-
                Requests per minute for the applicable limiter, when evaluated.
                Authenticated requests use the credential limit; an IP rejection
                uses the IP limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_not_found'
              example:
                error:
                  code: not_found
                  message: The resource does not exist in the current organization.
                  request_id: req_example
        '409':
          description: >-
            The channel or authorization cannot accept this operation. Read the
            error description before retrying.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request identifier for support and diagnostics; also included in
                error bodies.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
              required: false
              description: >-
                Organization-scoped API responses must not be cached. May be
                absent for requests rejected before routing.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '120'
              required: false
              description: >-
                Requests per minute for the applicable limiter, when evaluated.
                Authenticated requests use the credential limit; an IP rejection
                uses the IP limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_conflict'
              example:
                error:
                  code: conflict
                  message: >-
                    The channel or authorization cannot accept this operation.
                    Read the error description before retrying.
                  request_id: req_example
        '429':
          description: The IP or authenticated credential exceeded its request limit.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request identifier for support and diagnostics; also included in
                error bodies.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
              required: false
              description: >-
                Organization-scoped API responses must not be cached. May be
                absent for requests rejected before routing.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '120'
              required: false
              description: >-
                Requests per minute for the applicable limiter, when evaluated.
                Authenticated requests use the credential limit; an IP rejection
                uses the IP limit.
            Retry-After:
              schema:
                type: string
                example: '60'
              required: true
              description: Seconds to wait before retrying the request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_rate_limit_exceeded'
              example:
                error:
                  code: rate_limit_exceeded
                  message: >-
                    The IP or authenticated credential exceeded its request
                    limit.
                  request_id: req_example
        '500':
          description: >-
            Unexpected server failure. Include the request ID when contacting
            support.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request identifier for support and diagnostics; also included in
                error bodies.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
              required: false
              description: >-
                Organization-scoped API responses must not be cached. May be
                absent for requests rejected before routing.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '120'
              required: false
              description: >-
                Requests per minute for the applicable limiter, when evaluated.
                Authenticated requests use the credential limit; an IP rejection
                uses the IP limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_internal_error'
              example:
                error:
                  code: internal_error
                  message: >-
                    Unexpected server failure. Include the request ID when
                    contacting support.
                  request_id: req_example
        '503':
          description: >-
            Authentication infrastructure is unavailable or rate limited. Honor
            Retry-After when provided.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request identifier for support and diagnostics; also included in
                error bodies.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
              required: false
              description: >-
                Organization-scoped API responses must not be cached. May be
                absent for requests rejected before routing.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '120'
              required: false
              description: >-
                Requests per minute for the applicable limiter, when evaluated.
                Authenticated requests use the credential limit; an IP rejection
                uses the IP limit.
            Retry-After:
              schema:
                type: string
                example: '60'
              required: true
              description: Seconds to wait before retrying the request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_service_unavailable'
              example:
                error:
                  code: service_unavailable
                  message: >-
                    Authentication infrastructure is unavailable or rate
                    limited. Honor Retry-After when provided.
                  request_id: req_example
      security:
        - ClerkSessionBearer: []
components:
  schemas:
    NotificationChannel:
      type: object
      properties:
        id:
          type: string
          format: uuid
        type:
          type: string
          enum:
            - email
            - slack
        owner:
          type: string
          enum:
            - personal
            - organization
        destination:
          anyOf:
            - type: object
              properties:
                type:
                  type: string
                  enum:
                    - email
                recipients:
                  type: array
                  items:
                    type: string
                    format: email
              required:
                - type
                - recipients
            - type: object
              properties:
                type:
                  type: string
                  enum:
                    - slack
                channel_id:
                  type: string
                channel_name:
                  type: string
              required:
                - type
                - channel_id
                - channel_name
            - type: 'null'
        delivery_summary:
          type: object
          properties:
            days:
              type: number
              enum:
                - 30
            events:
              type: integer
            suppliers:
              type: integer
            deadlines:
              type: integer
          required:
            - days
            - events
            - suppliers
            - deadlines
      required:
        - id
        - type
        - owner
        - destination
        - delivery_summary
    Error_validation_error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - validation_error
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_invalid_token:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - invalid_token
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_forbidden_token_disabled_organization_required_insufficient_role_mfa_required:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - forbidden
                - token_disabled
                - organization_required
                - insufficient_role
                - mfa_required
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_not_found:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - not_found
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_conflict:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - conflict
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_rate_limit_exceeded:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - rate_limit_exceeded
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_internal_error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - internal_error
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_service_unavailable:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - service_unavailable
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
  securitySchemes:
    ClerkSessionBearer:
      type: http
      scheme: bearer
      description: Clerk session with an active organization.

````