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

# Ask about up to 32 actions at once

> The AuthZEN batch form of `evaluation`. `subject`, `action`, `resource`
and `context` at the top level are defaults for every evaluation that
does not state its own. Results come back in the order asked and each
is exactly the answer `evaluation` would have given.

The batch is all or nothing: if any evaluation is refused (a subject
that is not the caller, a supplied principal-side entity, a malformed
part) the whole request is refused and nothing is evaluated. At most 32
evaluations; only the `execute_all` semantic is supported.




## OpenAPI

````yaml /api/access-api.yaml post /access/v1/evaluations
openapi: 3.0.3
info:
  title: Noetive Access API (agent-facing)
  version: 0.1.0
  description: >
    The agent-facing surface of `access.noetive.io`: what a program holding an

    agent credential calls.


    This revision documents **`agents/v1`**: create agents, their keys and

    their mailboxes from your own service, without the dashboard; and

    **`access/v1`**: ask whether an agent may take an action, as an OpenID

    AuthZEN 1.0 policy decision point. `approvals/v1` is served from the same

    host and is documented in a later revision of this document.


    Every operation is a JSON `POST`, including the ones that only read, except

    the public discovery document, which is a `GET`. Any

    other method on a known operation is answered `405`, and an operation that

    does not exist is answered `404` `not_found`.


    ## Who may call it


    The caller is an agent with **May create agents and keys** turned on by a

    person in the dashboard. That agent is the *provisioner*. It presents one

    of:


    - a static key (`keya_…`) as `Authorization: Bearer <key>`;

    - an access token (a JWT) for the audience `https://access.noetive.io`
      carrying the scope `agent:provision`. The token endpoint grants that
      scope only to an agent that may create agents; a token without it is
      answered `403` `insufficient_scope`.

    Everything a provisioner creates belongs to the provisioner's own tenant.

    No request field names a tenant, so a credential can never create anything

    in another tenant.


    ## What a provisioner may do


    - **It never grants more than it holds.** An agent it creates reaches at
      most the Bud scopes, namespaces, global namespaces and roles the
      provisioner itself holds. This is checked on `create` and again on
      `rotate_key`.
    - **It cannot create provisioners.** An agent it creates can never be given
      this permission, so a leaked credential cannot copy itself.
    - **It sees only what it created.** Agents made in the dashboard or by
      another provisioner are answered as `not_found`, exactly like agents that
      do not exist.
    - **Policy still applies.** The tenant's agent limit and the organization's
      and tenant's rules apply to every call.

    ## A refused call leaves no agent and no working key


    `create` answers only once the agent's mailbox exists, and the response

    carries its address. A call answered with a refusal has removed the agent,

    and no key from it works, so it is safe to retry. After an

    `internal_error` or a dropped connection, retry too: the retry either

    succeeds or answers `name_taken` naming the agent the first attempt made.


    An address stays reserved after its agent is gone, including one from a

    create interrupted after its mailbox was set up. Asking for it again is

    answered `local_part_taken` without an `agent_id`; choose another.


    An agent must reach something: at least one Bud scope, a namespace, the

    shared `global` namespace or a role. A request for an agent reaching

    nothing is `invalid_request`.


    ## Retrying after a lost response


    Give each agent a `name` derived from your own record of it, such as a

    ticket or customer id. If a response is lost after the call succeeded, the

    retry is refused with `name_taken` and the `agent_id` it already created,

    and because the name is yours that id is the agent you meant. Call

    `rotate_key` with it to get a working key.


    `revoke_key` of a key that is already revoked answers `not_found`.


    ## Errors


    A refusal is a JSON object with `code` and `error`, at the HTTP status the

    code maps to. Branch on the status, then within it on the code. `error` is

    a sentence for a person and may change.


    | code | status | meaning |

    | --- | --- | --- |

    | `invalid_request` | 400 | The body is malformed, a field is wrong, or a
    `before` cursor is not one the API issued. |

    | `unauthorized` | 401 | No credential, or it is unknown, revoked, expired
    or its agent is disabled. |

    | `not_billable` | 402 | The organization cannot create mailboxes until it
    has a payment method. No agent or key from the call remains. |

    | `insufficient_scope` | 403 | The token lacks the `agent:provision` scope.
    |

    | `not_a_provisioner` | 403 | The agent does not have **May create agents
    and keys**, or was itself created by an agent. |

    | `forbidden_by_policy` | 403 | The organization's or tenant's rules forbid
    this agent from creating agents. |

    | `exceeds_provisioner` | 403 | The request asks for more than the
    provisioner itself holds, or, on `rotate_key`, the agent has since been
    given more than that. |

    | `not_found` | 404 | No such agent or key among those this provisioner
    created, or no such operation. |

    | `method_not_allowed` | 405 | The operation exists but only answers `POST`.
    |

    | `agent_limit` | 409 | The tenant holds as many agents as its policy
    allows. |

    | `local_part_taken` | 409 | The address is in use. `agent_id` is set when
    this provisioner created it. |

    | `name_taken` | 409 | The name is in use. `agent_id` is set when this
    provisioner created it. |

    | `conflict` | 409 | Another change to the same agent's key landed first.
    Retry. |

    | `rate_limited` | 429 | A limit was reached. `retry_after_ms`, `scope` and
    `limit` say which and for how long. |

    | `internal_error` | 500 | Something went wrong that is not about the
    request. |

    | `mailbox_unavailable` | 503 | The mailbox could not be set up just now. No
    agent or key from the call remains; retry after the `Retry-After` header's
    seconds, with backoff. |

    | `policy_unavailable` | 503 | Policy could not be evaluated, so the call
    was refused. Retry with backoff. |

    | `temporarily_unavailable` | 503 | The credential could not be checked just
    now. Keep it and retry. |
servers:
  - url: https://access.noetive.io
    description: Noetive Access
security:
  - bearerAuth: []
paths:
  /access/v1/evaluations:
    post:
      summary: Ask about up to 32 actions at once
      description: |
        The AuthZEN batch form of `evaluation`. `subject`, `action`, `resource`
        and `context` at the top level are defaults for every evaluation that
        does not state its own. Results come back in the order asked and each
        is exactly the answer `evaluation` would have given.

        The batch is all or nothing: if any evaluation is refused (a subject
        that is not the caller, a supplied principal-side entity, a malformed
        part) the whole request is refused and nothing is evaluated. At most 32
        evaluations; only the `execute_all` semantic is supported.
      operationId: evaluateAccessBatch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchEvaluationRequest'
            example:
              subject:
                type: agent
                id: ag_01jb8x4m2fe0bv3c7y1tq9k2rd
              action:
                name: semantik.publish
              evaluations:
                - resource:
                    type: Namespace
                    id: ns_01jb8x4m2fe0bv3c7y1tq9k2rd
                - resource:
                    type: Namespace
                    id: ns_01jb8x4m3ae0bv3c8m5n7r2wxz
      responses:
        '200':
          description: One decision per evaluation, in order.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchDecision'
              example:
                evaluations:
                  - decision: true
                    context:
                      tier: allowed
                      rule_ids:
                        - agent.publish
                      messages: []
                  - decision: false
                    context:
                      tier: denied
                      rule_ids: []
                      messages: []
        '400':
          $ref: '#/components/responses/AccessRefusal'
        '401':
          $ref: '#/components/responses/AccessRefusal'
        '403':
          $ref: '#/components/responses/AccessRefusal'
        '404':
          $ref: '#/components/responses/AccessRefusal'
        '405':
          $ref: '#/components/responses/AccessRefusal'
        '500':
          $ref: '#/components/responses/AccessRefusal'
        '503':
          $ref: '#/components/responses/AccessRefusal'
components:
  schemas:
    BatchEvaluationRequest:
      type: object
      additionalProperties: false
      required:
        - evaluations
      properties:
        subject:
          $ref: '#/components/schemas/Subject'
        action:
          $ref: '#/components/schemas/Action'
        resource:
          $ref: '#/components/schemas/Resource'
        context:
          $ref: '#/components/schemas/EvaluationContext'
        options:
          type: object
          additionalProperties: false
          properties:
            evaluations_semantic:
              type: string
              enum:
                - execute_all
        evaluations:
          type: array
          minItems: 1
          maxItems: 32
          items:
            $ref: '#/components/schemas/EvaluationRequestPart'
    BatchDecision:
      type: object
      required:
        - evaluations
      properties:
        evaluations:
          type: array
          items:
            $ref: '#/components/schemas/Decision'
    Subject:
      type: object
      additionalProperties: false
      required:
        - type
        - id
      properties:
        type:
          type: string
          enum:
            - agent
        id:
          type: string
          description: Must be the agent the credential belongs to.
    Action:
      type: object
      additionalProperties: false
      required:
        - name
      properties:
        name:
          type: string
          description: >-
            An action of the vocabulary, such as `mail.send` or
            `commitment.create`.
    Resource:
      type: object
      additionalProperties: false
      required:
        - type
        - id
      properties:
        type:
          type: string
          description: The type the action takes; see the table on `evaluation`.
        id:
          type: string
          minLength: 1
          maxLength: 256
        properties:
          type: object
          additionalProperties: false
          description: Accepted on a `Commitment` only.
          properties:
            amount:
              $ref: '#/components/schemas/Amount'
    EvaluationContext:
      type: object
      additionalProperties: false
      description: Only `declared` may be sent.
      properties:
        declared:
          type: object
          additionalProperties: false
          properties:
            amount:
              $ref: '#/components/schemas/Amount'
            classification:
              type: string
              enum:
                - public
                - internal
                - confidential
                - restricted
              description: Can raise the sensitivity of the request and never lower it.
    EvaluationRequestPart:
      type: object
      additionalProperties: false
      properties:
        subject:
          $ref: '#/components/schemas/Subject'
        action:
          $ref: '#/components/schemas/Action'
        resource:
          $ref: '#/components/schemas/Resource'
        context:
          $ref: '#/components/schemas/EvaluationContext'
    Decision:
      type: object
      required:
        - decision
        - context
      properties:
        decision:
          type: boolean
          description: True only when `context.tier` is `allowed`.
        context:
          type: object
          required:
            - tier
            - rule_ids
            - messages
          properties:
            tier:
              type: string
              enum:
                - allowed
                - requires_approval
                - denied
            rule_ids:
              type: array
              items:
                type: string
              description: The rules that decided, at most 8; empty when nothing matched.
            messages:
              type: array
              items:
                type: string
              description: Their explanations; empty when they have none.
    AccessRefusal:
      type: object
      required:
        - code
        - error
      properties:
        code:
          type: string
          enum:
            - invalid_request
            - unauthorized
            - forbidden
            - not_found
            - method_not_allowed
            - internal_error
            - policy_unavailable
            - temporarily_unavailable
        error:
          type: string
          description: A sentence for a person. Do not branch on it.
    Amount:
      type: object
      additionalProperties: false
      required:
        - minor
        - currency
      properties:
        minor:
          type: integer
          format: int64
          minimum: 0
          description: Amount in the currency's minor unit (öre, cents).
        currency:
          type: string
          pattern: ^[A-Z]{3}$
          description: ISO 4217 code.
  responses:
    AccessRefusal:
      description: The request was refused. `code` says why.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AccessRefusal'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: |
        Either a key (`keya_…`) or an access token (a JWT) for the audience
        `https://access.noetive.io`. `agents/v1` needs the scope
        `agent:provision` and an agent with **May create agents and keys**;
        `access/v1` accepts any agent credential. Pass as
        `Authorization: Bearer <credential>`.

````

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