Quick start
Let's get you up and running on Forest Admin in minutes!
Please be sure of your agent type and version and pick the right documentation accordingly.
This is the documentation of the forest-express-sequelize and forest-express-mongoose Node.js agents that will soon reach end-of-support.
forest-express-sequelize v9 and forest-express-mongoose v9 are replaced by @forestadmin/agent v1.
Please check your agent type and version and read on or switch to the right documentation.
This is still the latest Ruby on Rails documentation of the forest_liana agent, you’re at the right place, please read on.
This is the documentation of the django-forestadmin Django agent that will soon reach end-of-support.
If you’re using a Django agent, notice that django-forestadmin v1 is replaced by forestadmin-agent-django v1.
If you’re using a Flask agent, go to the forestadmin-agent-flask v1 documentation.
Please check your agent type and version and read on or switch to the right documentation.
This is the documentation of the forestadmin/laravel-forestadmin Laravel agent that will soon reach end-of-support.
If you’re using a Laravel agent, notice that forestadmin/laravel-forestadmin v1 is replaced by forestadmin/laravel-forestadmin v3.
If you’re using a Symfony agent, go to the forestadmin/symfony-forestadmin v1 documentation.
Please check your agent type and version and read on or switch to the right documentation.
Quick start
Step 1: Create an account and follow the onboarding
Go to https://app.forestadmin.com/signup, create an account and install your project.
At the end of your onboarding, you will out-of-the-box be able to:
Access all your data (1)
Export your data (2)
Add a record (3)
View and edit a record (4)
Edit your UI (5)
Search and filter (6)

However, your business logic likely requires more features. What if you need to...
refund an order
upload new documents, accept or reject them, or ask customers to update their documents,
contact a customer or ask a team member to perform an action,
and much more?
It's possible with smart actions 👇
Step 2: Create a Smart Action
Let's say you want to let your customer support team to easily refund orders, you can quickly create a smart action.
Declare it in your /forest/orders.js file:
const { collection } = require('forest-express-sequelize');
collection('orders', {
actions: [{
name: 'Refund order',
}],
});Then implement it according to your business logic:
const { PermissionMiddlewareCreator } = require('forest-express-sequelize');
const permissionMiddlewareCreator = new PermissionMiddlewareCreator('orders');
...
router.post('/actions/refund-order', permissionMiddlewareCreator.smartAction(), (req, res) => {
// Add your own logic, like calling a Stripe API for instance
res.send({ success: 'Order refunded!' });
});
...
module.exports = router;You must make sure that all your Smart Actions routes are configured with the Smart Action middleware: permissionMiddlewareCreator.smartAction(). This is mandatory to ensure that all features built on top of Smart Actions work as expected (permissions, approval workflows,...).
Declare it in your /forest/orders.js file:
const { collection } = require('forest-express-mongoose');
collection('orders', {
actions: [{
name: 'Refund order',
}],
});Then implement it according to your business logic:
const { PermissionMiddlewareCreator } = require('forest-express-mongoose');
const permissionMiddlewareCreator = new PermissionMiddlewareCreator('orders');
...
router.post('/actions/refund-order', permissionMiddlewareCreator.smartAction(), (req, res) => {
// Add your own logic, like calling a Stripe API for instance
res.send({ success: 'Order refunded!' });
});
...
module.exports = router;You must make sure that all your Smart Actions routes are configured with the Smart Action middleware: permissionMiddlewareCreator.smartAction(). This is mandatory to ensure that all features built on top of Smart Actions work as expected (permissions, approval workflows,...).
Declare it in your /lib/forest_liana/collections/order.rb file:
class Forest::Order
include ForestLiana::Collection
collection :Order
action 'Refund order'
endThen declare the corresponding route:
Rails.application.routes.draw do
# MUST be declared before the mount ForestLiana::Engine.
namespace :forest do
post '/actions/refund-order' => 'orders#refund_order'
end
mount ForestLiana::Engine => '/forest'
endLastly, implement the action according to your business logic:
class Forest::OrdersController < ForestLiana::SmartActionsController
def refund_order
# Add your own logic, like calling a Stripe API for instance
render json: { success: 'Order refunded!' }
end
endYou must make sure that all your Smart Actions controllers extend from the ForestLiana::SmartActionsController. This is mandatory to ensure that all features built on top of Smart Actions work as expected (authentication, permissions, approval workflows,...)
Declare it in your app/forest/orders.py file:
from django_forest.utils.collection import Collection
from app.models import Order
class OrderForest(Collection):
def load(self):
self.actions = [{
'name': 'Refund order'
}]
Collection.register(OrderForest, Order)Ensure the file app/forest/__init__.py exists and contains the import of the previous defined class :
from app.forest.orders import OrderForestMake sure your project urls.py file include you app urls with the forest prefix.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('forest', include('app.urls')),
path('forest', include('django_forest.urls')),
path('admin/', admin.site.urls),
]Then declare the corresponding route:
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from . import views
app_name = 'app'
urlpatterns = [
path('/actions/refund-order', csrf_exempt(views.RefundOrderView.as_view()), name='refund-order'),
]Lastly, implement the action according to your business logic:
from django.http import JsonResponse
from django_forest.utils.views.action import ActionView
class RefundOrderView(ActionView):
def post(self, request, *args, **kwargs):
# Add your own logic, like calling a Stripe API for instance
return JsonResponse({'success': 'Order refunded!'})Note that Forest Admin takes care of the authentication thanks to the ActionView parent class view.
Declare it in your app/Models/Order.php file:
/**
* @return SmartAction
*/
public function refundOrder(): SmartAction
{
return $this->smartAction('single', 'refund order');
}Then declare the corresponding route:
Route::post('forest/smart-actions/order_refund-order', [OrdersController::class, 'refundOrder']);Lastly, implement the action according to your business logic:
<?php
namespace App\Http\Controllers;
use ForestAdmin\LaravelForestAdmin\Http\Controllers\ForestController;
use Illuminate\Http\JsonResponse;
/**
* Class OrdersController
*/
class OrdersController extends ForestController
{
/**
* @return JsonResponse
*/
public function refundOrder(): JsonResponse
{
return response()->json(
['success' => 'Order refunded!']
);
}
}Congrats! Now it's possible to refund an order!

Step 3: Deploy to Production
Now that you have a fully functional admin panel, the next logical step is to make it live, with your live (production) data. Click on Deploy to Production and follow the flow.

That's it! You are now fully operational on Forest Admin.
Next, we recommend reading about our recommended development workflow.
Last updated
Was this helpful?