> ## 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.

# Delete an agent

> Deletes an agent this provisioner created and revokes its keys. Its
address stays reserved and is never given to another agent.




## OpenAPI

````yaml /api/access-api.yaml post /agents/v1/delete
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:
  /agents/v1/delete:
    post:
      summary: Delete an agent
      description: |
        Deletes an agent this provisioner created and revokes its keys. Its
        address stays reserved and is never given to another agent.
      operationId: deleteAgent
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeleteAgentRequest'
            example:
              agent_id: ag_01jb8x4m2fe0bv3c7y1tq9k2rd
      responses:
        '200':
          description: The agent is deleted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Empty'
        '400':
          $ref: '#/components/responses/Refusal'
        '401':
          $ref: '#/components/responses/Refusal'
        '403':
          $ref: '#/components/responses/Refusal'
        '404':
          $ref: '#/components/responses/Refusal'
        '405':
          $ref: '#/components/responses/Refusal'
        '500':
          $ref: '#/components/responses/Refusal'
        '503':
          $ref: '#/components/responses/Refusal'
components:
  schemas:
    DeleteAgentRequest:
      type: object
      additionalProperties: false
      required:
        - agent_id
      properties:
        agent_id:
          type: string
    Empty:
      type: object
      additionalProperties: false
    Refusal:
      type: object
      required:
        - code
        - error
      properties:
        code:
          type: string
          enum:
            - invalid_request
            - unauthorized
            - not_billable
            - insufficient_scope
            - not_a_provisioner
            - forbidden_by_policy
            - exceeds_provisioner
            - not_found
            - method_not_allowed
            - agent_limit
            - local_part_taken
            - name_taken
            - conflict
            - rate_limited
            - internal_error
            - mailbox_unavailable
            - policy_unavailable
            - temporarily_unavailable
        error:
          type: string
          description: A sentence for a person. Do not branch on it.
        agent_id:
          type: string
          description: >-
            On `local_part_taken` and `name_taken`, the existing agent when this
            provisioner created it.
        retry_after_ms:
          type: integer
          description: On `rate_limited`, how long to wait before retrying.
        scope:
          type: string
          description: On `rate_limited`, whose limit it is, such as `tenant`.
        limit:
          type: string
          description: >-
            On `rate_limited`, which limit, such as `agent.create` or
            `concurrent_creates`.
  responses:
    Refusal:
      description: The request was refused. `code` says why.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Refusal'
          example:
            code: local_part_taken
            error: That address is already in use.
            agent_id: ag_01jb8x4m2fe0bv3c7y1tq9k2rd
  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.