New

Build production apps in 1 dayIntent API Templates →

Documentation

Intent API

One endpoint. Typed intents. Install from PyPI and npm — no public source repo required.

This documentation mirrors the shipped packages intent-api (PyPI) and @intent-api/react (npm). Framework source is not published as a public repository; install from the registries above.

Overview

Intent API is a constraint-driven API framework: instead of dozens of REST endpoints, every call is a typed intent — one POST body describing model, action, payload, and context. The backend dispatches to your services.

The frontend uses two hooks — useIntentQuery and useIntentMutation — backed by TanStack Query.

Need a full app scaffold? See paid templates.

Install

Backend (Python):

pip install intent-api

Frontend (React):

npm install @intent-api/react
# peer: react, @tanstack/react-query, axios

The intent protocol

Typical user-facing endpoint: POST /api/intent

{
  "model": "Todo",
  "action": "create",
  "payload": { "title": "Ship Intent API", "done": false },
  "context": { "type": "user", "team_id": "abc-123" }
}

IntentRequest fields

FieldDescription
modelResource name, e.g. "Todo", "User"
action"create" | "read" | "update" | "delete" | "list" | "custom"
idResource id for read/update/delete
payloadData for create/update/custom
commandNamed command when action is "custom"
contextCaller scope (role, team, org)
skip / limitPagination for list

Python (FastAPI)

Subclass IntentService, register with IntentRouter, then include_router(router.build(...)).

from fastapi import FastAPI
from intent_api import IntentRouter, IntentService, MutationResponse

app = FastAPI()

class TodoService(IntentService):
    async def create(self, *, db, user, context, payload):
        return MutationResponse(success=True, id="1", message="Todo created")

    async def list(self, *, db, user, context, skip, limit):
        return {"items": [], "total": 0}

router = IntentRouter()
router.register("Todo", TodoService())

app.include_router(router.build(
    get_user=my_auth_dependency,
    get_db=my_db_dependency,
))

Auth is your choice: pass a get_user dependency (e.g. Clerk JWT verification). Guest and machine surfaces use additional router builders — see Multiple surfaces.

React

Wrap the app with IntentApiProvider (base URL + token callback + default context). Use hooks in components.

import { IntentApiProvider, useIntentQuery, useIntentMutation, intentFactory } from "@intent-api/react";

<IntentApiProvider
  baseURL="https://api.myapp.com"
  getToken={async () => (await getToken()) ?? null}
  defaultContext={{ type: "user" }}
>
  <App />
</IntentApiProvider>

const { data } = useIntentQuery("Todo", "list", { skip: 0, limit: 20 });
const createTodo = useIntentMutation("Todo", "create");
createTodo.mutate(intentFactory("Todo", "create", { payload: { title: "Hi" } }));

Query keys follow ["intent", model, ...] so you can invalidate after mutations.

Multiple surfaces

Backend: build (standard), build_admin, build_guest, build_machine for different prefixes and auth rules.

React: matching hooks, e.g.

useIntentQuery("Todo", "list");
useAdminIntentQuery("User", "list");
useGuestIntentQuery("Post", "list");
useMachineIntentMutation("Event", "ingest_batch");

Default paths are /api/intent, /api/admin-intent, etc. Override via provider endpoints if needed.

DevTools

With debug=True on the router, the backend can expose a registry for click-to-source. On the client, wrap with IntentDevToolsProvider and render IntentDevTools in development to inspect intents and open handlers in Cursor/VS Code.

License

Free for commercial use under the Intent API License (IACL): no competing framework or hosted substitute. Full text ships with the PyPI and npm packages.