openapi: 3.0.3
info:
  title: Schedula APIs Service API
  version: 1.0.0
  description: 'OpenAPI document for backend management API templates and runtime
    execution. The `apis` service is intended to help build new backend APIs such
    as feature flags, incident workflows, and external sync endpoints. The runtime
    route creates a temporary contract document, executes the event pipeline, and
    then deletes the temporary document when the request finishes.

    '
externalDocs:
  description: Docs
  url: https://api.formulas.dev/docs/apis/docs.json
servers:
- url: https://api.formulas.dev/
tags:
- name: APIs
  description: API template management and runtime event execution.
components:
  securitySchemes:
    authToken:
      type: apiKey
      in: header
      name: Authentication-Token
  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
        details:
          type: object
          additionalProperties: true
      example:
        error: invalid_payload
        message: Invalid payload
    ApiJsonWithRefs:
      title: JSON with Runtime References
      description: 'Any JSON value. Objects may include runtime placeholders such
        as `$ctx` and item references such as `$ref`, resolved by the workflow engine
        at execution time. `$ctx` paths can embed nested `$$ctx` tokens and optional
        `|(<expression>)` transforms.

        '
      oneOf:
      - type: string
      - type: number
      - type: integer
      - type: boolean
      - type: 'null'
      - type: array
        items:
          $ref: '#/components/schemas/ApiJsonWithRefs'
      - type: object
        properties:
          $ref:
            type: string
            pattern: ^/items(/[^/]+){2,3}$
            description: Reference to an item resource.
          $ctx:
            type: string
            pattern: ^[^/]+$
            description: Runtime context path resolved by the engine.
        additionalProperties:
          $ref: '#/components/schemas/ApiJsonWithRefs'
    ApiCtxRef:
      title: Context Reference
      description: RefResolver expression that uses `$ctx`, including nested `$$ctx`
        tokens and optional `|(<expression>)` transforms.
      type: object
      required:
      - $ctx
      additionalProperties: false
      properties:
        $ctx:
          type: string
          minLength: 1
    ApiDocRef:
      title: Document Reference
      description: RefResolver expression that uses `$ref`, including optional `|(<expression>)`
        transforms.
      type: object
      required:
      - $ref
      additionalProperties: false
      properties:
        $ref:
          type: string
          minLength: 1
    ApiUpdateOperation:
      title: Update Payload
      description: MongoDB-style update document used by `update.item` and `update.contract`
        effects.
      type: object
      minProperties: 1
      maxProperties: 1
      propertyNames:
        pattern: ^\$[A-Za-z][A-Za-z0-9_]*$
      patternProperties:
        ^\$set$:
          type: object
        ^\$unset$:
          oneOf:
          - type: string
          - type: array
            items:
              type: string
          - type: object
        ^\$inc$:
          type: object
        ^\$push$:
          type: object
        ^\$addToSet$:
          type: object
        ^\$pull$:
          type: object
        ^\$rename$:
          type: object
        ^\$min$:
          type: object
        ^\$max$:
          type: object
        ^\$mul$:
          type: object
        ^\$currentDate$:
          type: object
      additionalProperties:
        type: object
    ApiRequestKwargs:
      title: Requests Kwargs
      description: Supported subset of `requests.request(...)` kwargs for `http.request`
        effects.
      type: object
      required:
      - url
      additionalProperties: false
      properties:
        method:
          type: string
          enum:
          - GET
          - POST
          - PUT
          - PATCH
          - DELETE
          - HEAD
          - OPTIONS
          description: HTTP method used for the outbound call.
        url:
          type: string
          minLength: 1
          description: Absolute request URL.
        params:
          oneOf:
          - type: object
          - type: array
          - type: string
          description: Query string parameters.
        data:
          oneOf:
          - type: object
          - type: array
          - type: string
          - type: number
          - type: boolean
          - type: 'null'
          description: Raw or form request body.
        json:
          description: JSON request body.
        headers:
          type: object
          description: Request headers.
          additionalProperties:
            oneOf:
            - type: string
            - type: 'null'
        cookies:
          type: object
          description: Request cookies.
          additionalProperties:
            type: string
        files:
          type: object
          description: Files payload compatible with `requests`.
          additionalProperties: true
        auth:
          oneOf:
          - type: array
            minItems: 2
            maxItems: 2
            items:
              type: string
          - type: object
            required:
            - username
            - password
            additionalProperties: false
            properties:
              username:
                type: string
              password:
                type: string
          description: Basic auth credentials.
        timeout:
          oneOf:
          - type: number
          - type: array
            minItems: 2
            maxItems: 2
            items:
              type: number
          description: Single timeout or `(connect, read)` pair.
        allow_redirects:
          type: boolean
        proxies:
          type: object
          additionalProperties:
            type: string
        hooks:
          type: object
        stream:
          type: boolean
        verify:
          oneOf:
          - type: boolean
          - type: string
          description: TLS verification flag or CA bundle path.
        cert:
          oneOf:
          - type: string
          - type: array
            minItems: 2
            maxItems: 2
            items:
              type: string
          description: Client certificate path or `(cert, key)` pair.
    ApiEditMembers:
      title: Edit Members
      description: Batch membership edits for `update.group` effects.
      type: object
      additionalProperties: false
      properties:
        add_members:
          $ref: '#/components/schemas/ApiSubjectListOrRef'
        remove_members:
          $ref: '#/components/schemas/ApiSubjectListOrRef'
        promote_admins:
          $ref: '#/components/schemas/ApiSubjectListOrRef'
        demote_admins:
          $ref: '#/components/schemas/ApiSubjectListOrRef'
        ban_members:
          $ref: '#/components/schemas/ApiSubjectListOrRef'
        unban_members:
          $ref: '#/components/schemas/ApiSubjectListOrRef'
    ApiSubjectListOrRef:
      oneOf:
      - type: array
        items:
          oneOf:
          - type: string
            pattern: ^[ug]:.+$
          - $ref: '#/components/schemas/ApiJsonWithRefs'
      - $ref: '#/components/schemas/ApiJsonWithRefs'
    ApiNotifyKwargs:
      title: Notification Kwargs
      description: Notification payload passed to the notifications service.
      type: object
      required:
      - event
      - targets
      additionalProperties: false
      properties:
        event:
          type: string
          minLength: 1
          description: Notification event name.
        targets:
          description: Map of principal to delivery channels.
          oneOf:
          - type: object
            additionalProperties:
              type: array
              minItems: 1
              items:
                type: string
                minLength: 1
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        created_by:
          type: string
        payload:
          type: object
          additionalProperties: true
        severity:
          type: string
          enum:
          - info
          - warning
          - error
          - success
        persist:
          oneOf:
          - type: boolean
          - type: string
          - type: number
          - type: 'null'
        sender_principal:
          type: string
    ApiScheduleEvent:
      title: Scheduled Event
      description: Event schedule entry used by `schedule.event`.
      type: object
      required:
      - event_name
      properties:
        event_name:
          type: string
          minLength: 1
        at:
          oneOf:
          - type: string
            format: date-time
          - $ref: '#/components/schemas/ApiCtxRef'
        cron:
          oneOf:
          - type: string
            minLength: 1
          - $ref: '#/components/schemas/ApiCtxRef'
        contract_id:
          type: string
        payload:
          $ref: '#/components/schemas/ApiJsonWithRefs'
        actor_id:
          type: string
          minLength: 1
      oneOf:
      - required:
        - at
      - required:
        - cron
    ApiCredit:
      title: Credit Operation
      description: Credit transfer or balance payload used by credits effects.
      type: object
      required:
      - product
      properties:
        wallet_id:
          oneOf:
          - type: integer
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        user_id:
          oneOf:
          - type: integer
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        to_wallet_id:
          oneOf:
          - type: integer
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        to_user_id:
          oneOf:
          - type: integer
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        negative:
          oneOf:
          - type: boolean
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        product:
          oneOf:
          - type: string
            minLength: 1
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        amount:
          oneOf:
          - type: number
            minimum: 0
          - $ref: '#/components/schemas/ApiJsonWithRefs'
      allOf:
      - anyOf:
        - required:
          - wallet_id
          not:
            required:
            - user_id
        - required:
          - user_id
          not:
            required:
            - wallet_id
        - required: []
          not:
            required:
            - wallet_id
            - user_id
      - anyOf:
        - not:
            required:
            - amount
            - to_wallet_id
            - to_user_id
        - required:
          - amount
          not:
            required:
            - to_wallet_id
            - to_user_id
        - required:
          - amount
          - to_wallet_id
          not:
            required:
            - to_user_id
        - required:
          - amount
          - to_user_id
          not:
            required:
            - to_wallet_id
    ApiEffect:
      title: Effect
      description: 'Action executed when an API event is triggered. The available
        fields depend on `type` and mirror the server-side `TEMPLATE_CREATE_SCHEMA`.
        Practical examples include `http.request` for webhooks, `notify` for user
        or `email:<address>` delivery, and `raise` for explicit HTTP error responses.

        '
      type: object
      required:
      - type
      additionalProperties: false
      properties:
        type:
          type: string
          description: Supported effect type.
          enum:
          - create.item
          - delete.item
          - update.item
          - get.item
          - list.item
          - get.contract
          - execute.event
          - iter.effects
          - try.except
          - custom.function
          - update.local
          - create.group
          - update.group
          - update.contract
          - delete.contract
          - use.credits
          - charge.credits
          - transfers.credits
          - balance.credits
          - if.else
          - schedule.event
          - unschedule.event
          - http.request
          - notify
          - raise
          - lock
        title:
          type: string
        description:
          type: string
        projection:
          type: object
          description: Optional projection used by `get.item` or `get.contract`.
        default:
          description: Fallback value returned when `get.item` or `get.contract` cannot
            find the requested document(s).
          oneOf:
          - type: object
          - type: array
          - type: string
          - type: number
          - type: boolean
          - type: 'null'
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        update:
          oneOf:
          - $ref: '#/components/schemas/ApiUpdateOperation'
          - type: array
            items:
              $ref: '#/components/schemas/ApiUpdateOperation'
        updates:
          oneOf:
          - type: object
            additionalProperties:
              oneOf:
              - $ref: '#/components/schemas/ApiUpdateOperation'
              - type: array
                items:
                  $ref: '#/components/schemas/ApiUpdateOperation'
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        request:
          $ref: '#/components/schemas/ApiRequestKwargs'
        requests:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ApiRequestKwargs'
        output:
          type: string
          enum:
          - response
          - full
          - ok
          - code
          description: Output mode for `http.request` effects.
        item_id:
          oneOf:
          - type: string
          - $ref: '#/components/schemas/ApiJsonWithRefs'
          - type: array
            items:
              oneOf:
              - type: string
              - $ref: '#/components/schemas/ApiJsonWithRefs'
        group_id:
          oneOf:
          - type: string
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        sub:
          oneOf:
          - type: string
            pattern: ^[gu]:[\w\d]+$
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        item:
          type: object
          title: Item Document
          description: Item document inserted by `create.item`. Fields mirror the
            item CRUD document format; omitted metadata fields are filled by the effect
            runtime.
          required:
          - category
          additionalProperties: false
          properties:
            _id:
              description: Optional explicit Mongo item identifier. If omitted, `create.item`
                generates a UUID.
              oneOf:
              - type: string
                minLength: 1
              - $ref: '#/components/schemas/ApiJsonWithRefs'
            id:
              description: Serialized response identifier; accepted for projected
                or pre-serialized item payloads.
              oneOf:
              - type: string
                minLength: 1
              - $ref: '#/components/schemas/ApiJsonWithRefs'
            category:
              description: Normalized item category.
              oneOf:
              - type: string
                minLength: 1
              - $ref: '#/components/schemas/ApiJsonWithRefs'
            data:
              description: Application data stored under the item document.
              oneOf:
              - type: object
                additionalProperties: true
              - $ref: '#/components/schemas/ApiJsonWithRefs'
            files:
              description: Stored file metadata keyed by logical file path.
              oneOf:
              - type: object
                additionalProperties:
                  type: object
                  additionalProperties: true
                  properties:
                    storage_key:
                      type: string
                    content_type:
                      type: string
                      nullable: true
                    size:
                      type: integer
                      minimum: 0
              - $ref: '#/components/schemas/ApiJsonWithRefs'
            acl_dom:
              description: Casbin domain owning the item. If omitted, `create.item`
                defaults to the actor user domain.
              oneOf:
              - type: string
                minLength: 1
              - $ref: '#/components/schemas/ApiJsonWithRefs'
            grants_ref:
              description: Optional grants reference used by ACL-aware item projections.
              oneOf:
              - type: string
                nullable: true
              - $ref: '#/components/schemas/ApiJsonWithRefs'
            public:
              description: Whether the item is marked public in the stored document.
              oneOf:
              - type: boolean
              - $ref: '#/components/schemas/ApiJsonWithRefs'
            created_by:
              description: Principal that created the item. Defaults to the effect
                actor.
              oneOf:
              - type: string
                minLength: 1
              - $ref: '#/components/schemas/ApiJsonWithRefs'
            updated_by:
              description: Principal that last updated the item. Defaults to the effect
                actor.
              oneOf:
              - type: string
                minLength: 1
              - $ref: '#/components/schemas/ApiJsonWithRefs'
            created_at:
              description: Creation timestamp. Defaults to the effect execution time.
              oneOf:
              - type: string
                format: date-time
              - $ref: '#/components/schemas/ApiJsonWithRefs'
            updated_at:
              description: Last update timestamp. Defaults to the effect execution
                time.
              oneOf:
              - type: string
                format: date-time
              - $ref: '#/components/schemas/ApiJsonWithRefs'
        filter:
          type: object
          description: Filter used by `list.item`.
          required:
          - category
          additionalProperties: false
          properties:
            category:
              type: string
              minLength: 1
              description: Category to list.
            mq:
              $ref: '#/components/schemas/ApiJsonWithRefs'
            projection:
              type: object
            include_data:
              type: boolean
            mode:
              type: string
            enforce_acl:
              type: boolean
            sort:
              type: string
            limit:
              type: integer
              minimum: 1
            offset:
              type: integer
              minimum: 0
        actor_id:
          oneOf:
          - type: string
            minLength: 1
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        payload:
          type: object
          description: Optional payload override used by `execute.event` and nested
            iterations.
          oneOf:
          - type: object
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        params:
          type: object
          description: Optional path-parameter override used by `execute.event` and
            nested iterations.
          oneOf:
          - type: object
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        args:
          type: object
          description: Optional query-argument override used by `execute.event`, nested
            iterations  or `custom.function`.
          oneOf:
          - type: object
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        enforce_acl:
          type: boolean
          description: Whether the list effect should enforce ACL filtering.
        contracts_filter:
          type: object
          description: Query filter used by `list.contracts`.
          additionalProperties: false
          properties:
            mq:
              $ref: '#/components/schemas/ApiJsonWithRefs'
            projection:
              type: object
            enforce_acl:
              type: boolean
            sort:
              type: string
            limit:
              type: integer
              minimum: 1
            offset:
              type: integer
              minimum: 0
        raise:
          type: boolean
          default: true
          description: Raise when the HTTP response status code is >= 400.
        name:
          type: string
        group_type:
          type: string
        edit_members:
          $ref: '#/components/schemas/ApiEditMembers'
        notify:
          $ref: '#/components/schemas/ApiNotifyKwargs'
        message:
          type: string
          minLength: 1
          description: Human-readable error message used by `raise`. Omitting `message`
            is only allowed inside `try.except.except_effects` to reraises the captured
            exception.
        code:
          oneOf:
          - type: integer
            minimum: 100
            maximum: 599
            default: 400
          - type: string
            minLength: 1
          description: HTTP status code returned by `raise`, or Python code executed
            by `update.local`.
        details:
          type: object
          additionalProperties: true
          description: Optional structured error details returned by `raise`.
        key:
          type: string
          minLength: 1
          description: Logical key used by the effect, such as a response key or lock
            key.
        event_id:
          oneOf:
          - type: string
            minLength: 1
          - $ref: '#/components/schemas/ApiJsonWithRefs'
          - type: array
            minItems: 1
            items:
              oneOf:
              - type: string
                minLength: 1
              - $ref: '#/components/schemas/ApiJsonWithRefs'
        contract_ids:
          oneOf:
          - type: string
            minLength: 1
          - type: array
            minItems: 1
            items:
              oneOf:
              - type: string
                minLength: 1
              - $ref: '#/components/schemas/ApiJsonWithRefs'
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        template_id:
          description: Template id used by `create.contract`.
          oneOf:
          - type: string
            minLength: 1
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        context:
          description: Initial context used by `create.contract`.
          oneOf:
          - type: object
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        initial_state:
          description: Optional initial state used by `create.contract`.
          oneOf:
          - type: string
            minLength: 1
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        contract_id:
          oneOf:
          - type: string
            minLength: 1
          - $ref: '#/components/schemas/ApiJsonWithRefs'
          - type: array
            minItems: 1
            items:
              oneOf:
              - type: string
                minLength: 1
              - $ref: '#/components/schemas/ApiJsonWithRefs'
        event:
          $ref: '#/components/schemas/ApiScheduleEvent'
        events:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ApiScheduleEvent'
        event_name:
          oneOf:
          - type: string
            minLength: 1
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        state:
          oneOf:
          - type: string
            minLength: 1
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        iter:
          oneOf:
          - type: array
            items:
              type: object
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        effects:
          type: array
          items:
            $ref: '#/components/schemas/ApiEffect'
        func:
          oneOf:
          - type: string
            minLength: 1
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        kwargs:
          oneOf:
          - type: object
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        credit:
          $ref: '#/components/schemas/ApiCredit'
        credits:
          oneOf:
          - type: object
            additionalProperties:
              $ref: '#/components/schemas/ApiCredit'
          - $ref: '#/components/schemas/ApiJsonWithRefs'
        condition:
          title: Branch Condition
          description: Boolean literal or runtime reference resolver used by `if.else`
            branching. The branch sees the latest contract snapshot, including `local`
            updates from earlier effects.
          oneOf:
          - type: boolean
          - $ref: '#/components/schemas/ApiCtxRef'
          - $ref: '#/components/schemas/ApiDocRef'
        then_effects:
          type: array
          items:
            $ref: '#/components/schemas/ApiEffect'
        else_effects:
          type: array
          items:
            $ref: '#/components/schemas/ApiEffect'
        try_effects:
          type: array
          description: Nested effects executed in the `try` branch of `try.except`.
          items:
            $ref: '#/components/schemas/ApiEffect'
        except_effects:
          type: array
          description: Effect executed when `try_effects` raises.
          items:
            $ref: '#/components/schemas/ApiEffect'
        finally_effects:
          type: array
          description: Nested effects executed after `try.except`, regardless of outcome.
          items:
            $ref: '#/components/schemas/ApiEffect'
      allOf:
      - if:
          properties:
            type:
              const: create.item
        then:
          description: Create one item (`item` + `key`) or multiple named items (`items`).
          additionalProperties: false
          properties:
            type:
              const: create.item
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            item:
              $ref: '#/components/schemas/ApiEffect/properties/item'
            items:
              type: object
              additionalProperties:
                $ref: '#/components/schemas/ApiEffect/properties/item'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          anyOf:
          - required:
            - item
            - key
            not:
              required:
              - items
          - required:
            - items
            not:
              required:
              - item
              - key
      - if:
          properties:
            type:
              const: delete.item
        then:
          description: Delete one item or multiple items by id.
          additionalProperties: false
          properties:
            type:
              const: delete.item
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            item_id:
              $ref: '#/components/schemas/ApiEffect/properties/item_id'
          required:
          - item_id
      - if:
          properties:
            type:
              const: update.item
        then:
          description: Update one item (`item_id` + `update`) or a map of item updates
            (`updates`).
          additionalProperties: false
          properties:
            type:
              const: update.item
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            item_id:
              $ref: '#/components/schemas/ApiEffect/properties/item_id'
            update:
              $ref: '#/components/schemas/ApiEffect/properties/update'
            updates:
              $ref: '#/components/schemas/ApiEffect/properties/updates'
            projection:
              $ref: '#/components/schemas/ApiEffect/properties/projection'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          anyOf:
          - required:
            - item_id
            - update
            not:
              required:
              - item
              - updates
          - required:
            - updates
            not:
              required:
              - item_id
              - update
      - if:
          properties:
            type:
              const: get.item
        then:
          description: Fetch item document(s) and store the result in `local[key]`.
          additionalProperties: false
          properties:
            type:
              const: get.item
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            item_id:
              $ref: '#/components/schemas/ApiEffect/properties/item_id'
            projection:
              $ref: '#/components/schemas/ApiEffect/properties/projection'
            default:
              $ref: '#/components/schemas/ApiEffect/properties/default'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          required:
          - item_id
          - key
      - if:
          properties:
            type:
              const: list.item
        then:
          description: List items matching a category/filter and store them in `local[key]`.
          additionalProperties: false
          properties:
            type:
              const: list.item
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            enforce_acl:
              $ref: '#/components/schemas/ApiEffect/properties/enforce_acl'
            filter:
              $ref: '#/components/schemas/ApiEffect/properties/filter'
            actor_id:
              $ref: '#/components/schemas/ApiEffect/properties/actor_id'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          required:
          - filter
          - key
      - if:
          properties:
            type:
              const: list.contracts
        then:
          description: List contract summaries and store them in `local[key]`.
          additionalProperties: false
          properties:
            type:
              const: list.contracts
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            enforce_acl:
              $ref: '#/components/schemas/ApiEffect/properties/enforce_acl'
            filter:
              $ref: '#/components/schemas/ApiEffect/properties/contracts_filter'
            actor_id:
              $ref: '#/components/schemas/ApiEffect/properties/actor_id'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          required:
          - key
      - if:
          properties:
            type:
              const: get.contract
        then:
          description: Fetch API runtime document(s) and store the result in `local[key]`.
          additionalProperties: false
          properties:
            type:
              const: get.contract
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            contract_id:
              $ref: '#/components/schemas/ApiEffect/properties/contract_id'
            projection:
              $ref: '#/components/schemas/ApiEffect/properties/projection'
            default:
              $ref: '#/components/schemas/ApiEffect/properties/default'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          required:
          - contract_id
          - key
      - if:
          properties:
            type:
              const: execute.event
        then:
          description: Execute another event on this API runtime document or another
            document.
          additionalProperties: false
          properties:
            type:
              const: execute.event
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            event_name:
              $ref: '#/components/schemas/ApiEffect/properties/event_name'
            contract_id:
              $ref: '#/components/schemas/ApiEffect/properties/contract_id'
            state:
              $ref: '#/components/schemas/ApiEffect/properties/state'
            actor_id:
              $ref: '#/components/schemas/ApiEffect/properties/actor_id'
            payload:
              $ref: '#/components/schemas/ApiEffect/properties/payload'
            args:
              $ref: '#/components/schemas/ApiEffect/properties/args'
            params:
              $ref: '#/components/schemas/ApiEffect/properties/params'
          required:
          - event_name
      - if:
          properties:
            type:
              const: iter.effects
        then:
          description: Execute nested effects once for each item in `iter`.
          additionalProperties: false
          properties:
            type:
              const: iter.effects
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            iter:
              $ref: '#/components/schemas/ApiEffect/properties/iter'
            effects:
              $ref: '#/components/schemas/ApiEffect/properties/effects'
          required:
          - iter
          - effects
      - if:
          properties:
            type:
              const: custom.function
        then:
          description: Call a registered Python function and store the returned value
            in `local[key]`.
          additionalProperties: false
          properties:
            type:
              const: custom.function
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            func:
              $ref: '#/components/schemas/ApiEffect/properties/func'
            args:
              $ref: '#/components/schemas/ApiEffect/properties/args'
            kwargs:
              $ref: '#/components/schemas/ApiEffect/properties/kwargs'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          required:
          - func
          - key
      - if:
          properties:
            type:
              const: update.local
        then:
          description: Execute Python code that mutates or replaces local workflow
            state.
          additionalProperties: false
          properties:
            type:
              const: update.local
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            code:
              type: string
              minLength: 1
          required:
          - code
      - if:
          properties:
            type:
              const: create.group
        then:
          description: Create a group, bootstrap membership, and store the group principal
            in `local[key]`.
          additionalProperties: false
          properties:
            type:
              const: create.group
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            name:
              $ref: '#/components/schemas/ApiEffect/properties/name'
            group_type:
              $ref: '#/components/schemas/ApiEffect/properties/group_type'
            sub:
              $ref: '#/components/schemas/ApiEffect/properties/sub'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          required:
          - name
          - key
      - if:
          properties:
            type:
              const: create.contract
        then:
          description: Create a contract from a template and store its id in `local[key]`.
          additionalProperties: false
          properties:
            type:
              const: create.contract
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            template_id:
              $ref: '#/components/schemas/ApiEffect/properties/template_id'
            context:
              $ref: '#/components/schemas/ApiEffect/properties/context'
            payload:
              $ref: '#/components/schemas/ApiEffect/properties/payload'
            initial_state:
              $ref: '#/components/schemas/ApiEffect/properties/initial_state'
            actor_id:
              $ref: '#/components/schemas/ApiEffect/properties/actor_id'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          required:
          - template_id
          - context
          - key
      - if:
          properties:
            type:
              const: update.group
        then:
          description: Update group metadata or membership operations.
          additionalProperties: false
          properties:
            type:
              const: update.group
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            group_id:
              $ref: '#/components/schemas/ApiEffect/properties/group_id'
            edit_members:
              $ref: '#/components/schemas/ApiEffect/properties/edit_members'
            group_type:
              $ref: '#/components/schemas/ApiEffect/properties/group_type'
            name:
              $ref: '#/components/schemas/ApiEffect/properties/name'
          required:
          - group_id
          anyOf:
          - required:
            - edit_members
          - required:
            - group_type
          - required:
            - name
      - if:
          properties:
            type:
              const: update.contract
        then:
          description: Update the current API runtime document or a runtime-resolved
            map of documents.
          additionalProperties: false
          properties:
            type:
              const: update.contract
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            update:
              $ref: '#/components/schemas/ApiEffect/properties/update'
            updates:
              $ref: '#/components/schemas/ApiEffect/properties/updates'
            projection:
              $ref: '#/components/schemas/ApiEffect/properties/projection'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          anyOf:
          - required:
            - update
            not:
              required:
              - updates
          - required:
            - updates
            not:
              required:
              - update
      - if:
          properties:
            type:
              const: delete.contract
        then:
          description: Delete the current API runtime document.
          additionalProperties: false
          properties:
            type:
              const: delete.contract
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
      - if:
          properties:
            type:
              const: use.credits
        then:
          description: Consume credits from one wallet or a named set of wallets.
          additionalProperties: false
          properties:
            type:
              const: use.credits
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            credit:
              $ref: '#/components/schemas/ApiEffect/properties/credit'
            credits:
              $ref: '#/components/schemas/ApiEffect/properties/credits'
          anyOf:
          - required:
            - credits
            not:
              required:
              - credit
              - key
          - required:
            - credit
            not:
              required:
              - credits
              - key
      - if:
          properties:
            type:
              const: charge.credits
        then:
          description: Add credits to one wallet or a named set of wallets.
          additionalProperties: false
          properties:
            type:
              const: charge.credits
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            credit:
              $ref: '#/components/schemas/ApiEffect/properties/credit'
            credits:
              $ref: '#/components/schemas/ApiEffect/properties/credits'
          anyOf:
          - required:
            - credits
            not:
              required:
              - credit
              - key
          - required:
            - credit
            not:
              required:
              - credits
              - key
      - if:
          properties:
            type:
              const: transfers.credits
        then:
          description: Move credits between wallets/users.
          additionalProperties: false
          properties:
            type:
              const: transfers.credits
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            credit:
              $ref: '#/components/schemas/ApiEffect/properties/credit'
            credits:
              $ref: '#/components/schemas/ApiEffect/properties/credits'
          anyOf:
          - required:
            - credits
            not:
              required:
              - credit
              - key
          - required:
            - credit
            not:
              required:
              - credits
              - key
      - if:
          properties:
            type:
              const: balance.credits
        then:
          description: Read wallet balance and store it in `local[key]`.
          additionalProperties: false
          properties:
            type:
              const: balance.credits
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            credit:
              $ref: '#/components/schemas/ApiEffect/properties/credit'
            credits:
              $ref: '#/components/schemas/ApiEffect/properties/credits'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          anyOf:
          - required:
            - credits
            not:
              required:
              - credit
              - key
          - required:
            - credit
            - key
            not:
              required:
              - credits
      - if:
          properties:
            type:
              const: if.else
        then:
          description: Execute one of two nested effect lists based on `condition`.
          additionalProperties: false
          properties:
            type:
              const: if.else
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            condition:
              $ref: '#/components/schemas/ApiEffect/properties/condition'
            then_effects:
              $ref: '#/components/schemas/ApiEffect/properties/then_effects'
            else_effects:
              $ref: '#/components/schemas/ApiEffect/properties/else_effects'
          required:
          - condition
          anyOf:
          - required:
            - then_effects
          - required:
            - else_effects
      - if:
          properties:
            type:
              const: try.except
        then:
          description: Execute nested effects with optional exception and finally
            handlers.
          additionalProperties: false
          properties:
            type:
              const: try.except
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            try_effects:
              $ref: '#/components/schemas/ApiEffect/properties/try_effects'
            except_effects:
              $ref: '#/components/schemas/ApiEffect/properties/except_effects'
            finally_effects:
              $ref: '#/components/schemas/ApiEffect/properties/finally_effects'
          required:
          - try_effects
      - if:
          properties:
            type:
              const: schedule.event
        then:
          description: Schedule an event once (`event` + `key`) or a map of named
            schedules (`events`).
          additionalProperties: false
          properties:
            type:
              const: schedule.event
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            event:
              $ref: '#/components/schemas/ApiEffect/properties/event'
            events:
              $ref: '#/components/schemas/ApiEffect/properties/events'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          anyOf:
          - required:
            - event
            - key
            not:
              required:
              - events
          - required:
            - events
            not:
              required:
              - event
              - key
      - if:
          properties:
            type:
              const: unschedule.event
        then:
          description: Remove scheduled event(s) by id.
          additionalProperties: false
          properties:
            type:
              const: unschedule.event
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            event_id:
              $ref: '#/components/schemas/ApiEffect/properties/event_id'
          required:
          - event_id
      - if:
          properties:
            type:
              const: http.request
        then:
          description: Execute outbound HTTP request(s) and store response output
            in local state.
          additionalProperties: false
          properties:
            type:
              const: http.request
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            request:
              $ref: '#/components/schemas/ApiEffect/properties/request'
            requests:
              $ref: '#/components/schemas/ApiEffect/properties/requests'
            output:
              $ref: '#/components/schemas/ApiEffect/properties/output'
            raise:
              $ref: '#/components/schemas/ApiEffect/properties/raise'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
          anyOf:
          - required:
            - request
            - key
            not:
              required:
              - requests
          - required:
            - requests
            not:
              required:
              - request
              - key
      - if:
          properties:
            type:
              const: notify
        then:
          description: Create a notification, including external `email:<address>`
            targets.
          additionalProperties: false
          properties:
            type:
              const: notify
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            notify:
              $ref: '#/components/schemas/ApiEffect/properties/notify'
          required:
          - notify
      - if:
          properties:
            type:
              const: raise
        then:
          description: Abort the current request with an HTTP error response.
          additionalProperties: false
          properties:
            type:
              const: raise
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            message:
              $ref: '#/components/schemas/ApiEffect/properties/message'
            code:
              $ref: '#/components/schemas/ApiEffect/properties/code'
            details:
              $ref: '#/components/schemas/ApiEffect/properties/details'
      - if:
          properties:
            type:
              const: lock
        then:
          description: Run nested effects under a distributed lock.
          additionalProperties: false
          properties:
            type:
              const: lock
            title:
              $ref: '#/components/schemas/ApiEffect/properties/title'
            description:
              $ref: '#/components/schemas/ApiEffect/properties/description'
            key:
              $ref: '#/components/schemas/ApiEffect/properties/key'
            effects:
              $ref: '#/components/schemas/ApiEffect/properties/effects'
          required:
          - key
          - effects
      x-examples:
        webhookCall:
          summary: Call an external webhook
          value:
            type: http.request
            key: webhook_response
            output: full
            request:
              method: POST
              url: https://example.com/webhook
              json:
                event: created
        externalEmailNotification:
          summary: Notify an external email recipient
          value:
            type: notify
            notify:
              event: api.completed
              targets:
                email:customer@example.com:
                - email
        explicitApiError:
          summary: Abort an API request
          value:
            type: raise
            code: 422
            message: Invalid business rule
            details:
              field: amount
    ApiEventTrigger:
      title: Event Trigger
      description: 'Trigger source configuration. APIs templates primarily use `type:
        api`.

        '
      oneOf:
      - type: object
        required:
        - type
        - path
        additionalProperties: false
        properties:
          type:
            type: string
            enum:
            - api
          path:
            type: string
            minLength: 1
            description: Runtime path suffix exposed under `/apis/{template_id}/...`.
          method:
            type: string
            enum:
            - POST
            - GET
            - PUT
            - PATCH
            - DELETE
          payload_schema:
            type: object
            description: JSON Schema used to validate the incoming request body.
          allow_principals:
            oneOf:
            - type: array
              items:
                type: string
            - type: object
            description: Optional allow list for calling principals.
          deny_principals:
            oneOf:
            - type: array
              items:
                type: string
            - type: object
            description: Optional deny list for calling principals.
          allow_user_states:
            type: array
            items:
              type: string
              minLength: 1
          deny_user_states:
            type: array
            items:
              type: string
              minLength: 1
          response:
            $ref: '#/components/schemas/ApiJsonWithRefs'
            description: JSON response template for this API trigger. Use `$$ctx.payload`
              for the request body, `$$ctx.params.<name>` for captured path params,
              `$$ctx.args.<name>` for query-string args, `$$ctx.local` for effect
              state, `$$ctx.doc` for the contract document, and `$$ctx.user` for the
              authenticated actor.
          response_type:
            type: string
            enum:
            - json
            - redirect
            - file
            description: Select how the trigger response is returned. Use `json` for
              a JSON body, `redirect` for a redirect, or `file` to return the item
              file download response.
          status:
            oneOf:
            - type: integer
            - $ref: '#/components/schemas/ApiJsonWithRefs'
            description: Optional HTTP status code returned with the JSON response.
      - type: object
        required:
        - type
        - category
        - event
        additionalProperties: false
        properties:
          type:
            type: string
            enum:
            - db
          category:
            type: string
            minLength: 1
          event:
            type: string
            enum:
            - creation
            - update
            - read
            - delete
    ApiWorkflowEvent:
      title: Workflow Event
      description: One named event exposed by the API template.
      type: object
      additionalProperties: false
      properties:
        trigger:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/ApiEventTrigger'
        effects:
          type: array
          items:
            $ref: '#/components/schemas/ApiEffect'
    ApiEventRequest:
      type: object
      additionalProperties: true
      example:
        item_id: 507f1f77bcf86cd799439011
    ApiEventResponse:
      type: object
      additionalProperties: true
      example:
        ok: true
        event: join_event
paths:
  /apis/{template_id}/{dyn_path}:
    post:
      operationId: post_apis_by_template_id_by_dyn_path
      tags:
      - APIs
      summary: Execute API template event
      security:
      - authToken: []
      parameters:
      - name: template_id
        in: path
        required: true
        schema:
          type: string
      - name: dyn_path
        in: path
        required: true
        schema:
          type: string
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ApiEventRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiEventResponse'
    get:
      operationId: get_apis_by_template_id_by_dyn_path
      tags:
      - APIs
      summary: Execute API template event via GET
      security:
      - authToken: []
      parameters:
      - name: template_id
        in: path
        required: true
        schema:
          type: string
      - name: dyn_path
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiEventResponse'
    put:
      operationId: put_apis_by_template_id_by_dyn_path
      tags:
      - APIs
      summary: Execute API template event via PUT
      security:
      - authToken: []
      parameters:
      - name: template_id
        in: path
        required: true
        schema:
          type: string
      - name: dyn_path
        in: path
        required: true
        schema:
          type: string
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ApiEventRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiEventResponse'
    patch:
      operationId: patch_apis_by_template_id_by_dyn_path
      tags:
      - APIs
      summary: Execute API template event via PATCH
      security:
      - authToken: []
      parameters:
      - name: template_id
        in: path
        required: true
        schema:
          type: string
      - name: dyn_path
        in: path
        required: true
        schema:
          type: string
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ApiEventRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiEventResponse'
    delete:
      operationId: delete_apis_by_template_id_by_dyn_path
      tags:
      - APIs
      summary: Execute API template event via DELETE
      security:
      - authToken: []
      parameters:
      - name: template_id
        in: path
        required: true
        schema:
          type: string
      - name: dyn_path
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiEventResponse'
