Skip to content

Custom ViewSet actions

@action registers an additional HTTP endpoint when its ViewSet is included. A detail action uses {pk}; a collection action does not. It does not create a get_object() or get_request_data() helper.

Custom actions use declared HTTP permissions

Route registration evaluates the action's effective permission list before calling its handler. permission_classes=None inherits the ViewSet list; an explicit action list replaces it. A denial returns HTTP 403 with the permission's message and the handler is not called.

A checked detail action

In the ticket-desk application, this action returns a summary after the standard retrieve path performs its checks:

app/views.py
from starlette.requests import Request
from aksara import ModelViewSet
from aksara.api import action
from aksara.permissions import IsAuthenticated
from .models import Ticket


class TicketViewSet(ModelViewSet):
    model = Ticket
    prefix = "/api/tickets"
    permission_classes = [IsAuthenticated]
    ai_exposed = False
    stream_enabled = False

    @action(detail=True, methods=["GET"], path="summary", ai_exposed=False)
    async def summary(self, pk: str, request: Request):
        record = await self.retrieve(pk=pk, request=request)
        return {"id": record["id"], "subject": record["subject"]}

Register the ViewSet through the tutorial's include_viewset flow. The added path is GET /api/tickets/{pk}/summary, without a trailing slash. The handler receives pk, matching the generated path parameter. A parameter named id does not automatically rename that path parameter.

The action wrapper checks IsAuthenticated before this handler runs. The example still delegates to retrieve for the standard object lookup and serialization path. When an effective permission overrides has_object_permission, a detail action loads the target and evaluates that object decision before dispatch. Collection actions still require an application query scope, and applications still establish identity and tenant context before permission evaluation.

Decorator arguments

Argument Contract
detail Required boolean: detail or collection route
methods Required list of HTTP method names; normalized to uppercase
path Optional route segment, default method name
name Optional route name, default method name
summary, description Optional OpenAPI text; otherwise derived from the docstring
permission_classes HTTP and generated-tool permission override; None inherits the ViewSet list
ai_exposed Action exposure metadata, default true; other ViewSet/model/registration conditions still apply
requires_approval MCP signed approval-grant requirement, default false; not an HTTP approval workflow

The keywords are path and name, not url_path and url_name. There is no implicit default GET method when methods is omitted.

Inputs, writes, and transactions

FastAPI inspects the bound method signature. Annotate request as Request and define typed body/query parameters for your actual endpoint. A docstring is not input validation. For writes, validate fields and related objects, apply current authority and tenant rules, and use a transaction for database changes that must commit together.

Do not perform a direct ORM update and assume the action decorator applies all CRUD field-write restrictions. Replacing a generated handler with application code means owning those checks. A collection action also needs an explicit query scope; object permission does not filter an entire list automatically.

MCP is a separate execution path

Eligible custom actions can appear in generated MCP discovery when the model, ViewSet, action, and application exposure settings permit it. Discovery is permission-filtered, and MCP performs its own execution-time checks before its internal HTTP call reaches the same action permission wrapper.

requires_approval=True concerns signed, bounded MCP grants. It neither stores a durable approval workflow nor automatically gates direct HTTP calls. For work that must survive approval delay and worker loss, use Durable Operations.

Start with the official MCP client tutorial for authenticated tool execution and the permissions guide for synchronous application checks.