Skip to main content
The auto-generated CRUD layer covers list, get, create, update, and delete for every model. For anything more specific — status transitions, batch operations, or domain-specific actions — create a custom_api.py file in the module directory. The framework scans for this file automatically on startup and registers any routes it finds, so you never need to touch main.py.

When to use custom_api.py

Reach for custom_api.py when you need to:
  • Status transitions — mark a task as complete, confirm an order, archive a record
  • Batch operations — reassign multiple items at once, bulk-apply a tag
  • Domain-specific actions — send a notification, trigger a workflow, compute a derived value

Add custom endpoints to a module

1

Create custom_api.py in the module directory

Add the file alongside the generated files. For an orders module the layout looks like:
2

Import the router from api.py

Import router from .api — the generated router for this module. Do not import it from veloiq_framework; the router object must be the same instance the generator created so your routes are registered under the correct prefix.
3

Add routes using standard FastAPI decorators

Decorate functions with @router.post, @router.get, and so on, exactly as you would in any FastAPI application. The full example below adds a POST /{order_id}/confirm endpoint and a GET /pending list:
4

Verify the new endpoints appear in /docs

Restart the backend, or let uvicorn hot-reload pick up the file. Open http://localhost:8000/docs — the new endpoints appear under the module’s section alongside the generated CRUD routes.
Never edit the generated api.py. It is overwritten every time you run veloiq generate. Put all custom logic in custom_api.py.

Task-manager example

For the task-manager tutorial app, create backend/app/modules/tasks/custom_api.py to add a “mark as complete” action:
After the backend reloads, POST /task/{task_id}/complete appears in /docs under the task section.
Generate the custom_api.py stub automatically when you scaffold a module by passing the --with-custom-api flag: