Xano Standards
Auth token as first step, permission check from database, three-layer input validation, error response format, reusable functions, webhooks.
Core rule:
Xano is the backend. All business logic, permission checks, validation, and data integrity rules live in Xano — never in WeWeb, React, or any frontend. The frontend only calls Xano APIs and renders the result.
Contents
| # | Section |
|---|---|
| 1 | Developer Responsibilities |
| 2 | API Group Organization |
| 3 | Endpoint Naming Standard |
| 4 | Authentication — First Step |
| 5 | Permission Check |
| 6 | Input Validation |
| 7 | Error Response Format |
| 8 | Reusable Functions |
| 9 | Database Naming |
| 10 | Webhooks |
| 11 | Environment Variables |
| 12 | API Documentation |
| 13 | Definition of Done |
1. Xano Developer Responsibilities
| Area | Responsibility |
|---|---|
| API Design | Every endpoint is purposeful, named clearly, and documented. |
| Authentication | Every protected endpoint validates the auth token as the first step. |
| Validation | Every input is validated in Xano — do not trust frontend validation. |
| Business Logic | All rules, calculations, and workflows live in Xano. |
| Error Handling | Every endpoint returns a consistent, predictable error format. |
| Permissions | Role/ownership checks happen in Xano before any data operation. |
| Reusable Functions | Shared logic lives in Xano Functions, not duplicated across endpoints. |
| Documentation | Every API is documented before frontend integration starts. |
2. API Group (Workspace) Organization
Organize Xano APIs into logical groups by feature or app area.
Good Group Structure
Auth
POST /auth/login
POST /auth/signup
POST /auth/forgot-password
POST /auth/reset-password
GET /auth/me
Projects
GET /projects
POST /projects
GET /projects/:id
PATCH /projects/:id
DELETE /projects/:id
Workspace Members
GET /workspace/:id/members
POST /workspace/:id/members/invite
DELETE /workspace/:id/members/:member_id
Files
POST /files/upload
GET /files/:id
DELETE /files/:id
Webhooks
POST /webhooks/stripe
POST /webhooks/sendgrid
Bad Structure
Endpoints
POST /doStuff
POST /handleProject
GET /getData
POST /misc
3. Endpoint Naming Standard
Rules
| Rule | Standard |
|---|---|
| Format | kebab-case |
| Pattern | /resource or /resource/:id |
| Action naming | Use HTTP method, not verb in URL |
| Nested resources | /parent/:id/child |
| Webhooks | /webhooks/provider-name |
Good vs Bad
| Good | Bad |
|---|---|
GET /projects |
GET /getProjects |
POST /projects |
POST /createProject |
PATCH /projects/:id |
POST /updateProject |
DELETE /projects/:id |
POST /deleteProjectById |
POST /workspace/:id/members/invite |
POST /inviteMember |
Exception
For complex operations that don't map cleanly to CRUD, use an action noun:
POST /projects/:id/archive
POST /invitations/:id/accept
POST /invitations/:id/decline
POST /users/:id/suspend
4. Authentication Standard
Auth Token Validation — First Step in Every Protected Endpoint
Every endpoint that requires a logged-in user must validate the token before doing anything else.
In Xano
Step 1: Auth Token (built-in middleware)
→ If invalid: stop, return 401
→ If valid: continue, authUser variable is set
Step 2: Permission check (if role required)
→ Query user role from database
→ If not allowed: stop, return 403
Step 3: Business logic
Never skip the auth token step on protected endpoints.
Auth Requirements By Endpoint Type
| Endpoint Type | Auth Required | Role Check |
|---|---|---|
| Public API (e.g. contact form) | No | No |
| User-specific data | Yes | Owner check |
| Workspace operation | Yes | Workspace membership + role |
| Admin operation | Yes | Admin role from database |
| Webhook | No auth token, but signature verification | — |
5. Permission Check Standard
After auth token validation, check what the user is allowed to do.
Pattern
1. Get auth user ID from token.
2. Query workspace_members where user_id = auth.id AND workspace_id = input.workspace_id.
3. If no record found: return 403 FORBIDDEN.
4. Check role is allowed for this action.
5. If role not allowed: return 403 FORBIDDEN.
6. Proceed with operation.
Role Hierarchy
Define roles in a consistent order in every permission check:
owner > admin > manager > member > viewer
Document which roles can perform which actions:
| Action | Owner | Admin | Manager | Member | Viewer |
|---|---|---|---|---|---|
| View records | Yes | Yes | Yes | Yes | Yes |
| Create record | Yes | Yes | Yes | No | No |
| Edit record | Yes | Yes | Yes | Own only | No |
| Delete record | Yes | No | No | No | No |
| Manage members | Yes | Yes | No | No | No |
6. Input Validation Standard
Every endpoint must validate every input — even if the frontend also validates.
Validation Order in Xano
1. Check required fields are present (not null, not empty string).
2. Check field types (text, integer, email, UUID format).
3. Check field lengths (min/max characters, min/max numbers).
4. Check field values (valid enum option, valid date range, valid UUID that exists in DB).
5. Check business rules (workspace ownership, uniqueness, status allowed).
Required Fields Checklist
Validation Error Response
When validation fails, return structured errors:
{
"status": 422,
"code": "VALIDATION_ERROR",
"message": "Please fix the highlighted fields.",
"fields": {
"name": "Project name is required.",
"workspace_id": "Invalid workspace."
}
}
7. Error Response Standard
Every endpoint must return a consistent error format.
Standard Error Format
{
"status": 400,
"code": "ERROR_CODE",
"message": "Human-readable message for frontend to display."
}
Error Codes
| Code | HTTP Status | When to Use |
|---|---|---|
UNAUTHENTICATED |
401 | Token missing, expired, or invalid. |
FORBIDDEN |
403 | Authenticated but lacks permission. |
VALIDATION_ERROR |
422 | Input is missing or invalid. |
NOT_FOUND |
404 | Record does not exist or user cannot access it. |
CONFLICT |
409 | Duplicate data or conflicting state. |
RATE_LIMITED |
429 | Too many requests. |
INTERNAL_ERROR |
500 | Unexpected server error. |
EXTERNAL_SERVICE_ERROR |
502 | Third-party call failed (Stripe, email, etc.). |
In Xano
Use a Precondition or Custom Response block to return errors:
Precondition: Check field is not null
→ Fail: return 422 with code VALIDATION_ERROR and message "Field is required."
Return errors using the Create Variable + Return Response pattern with the standard structure above.
8. Reusable Functions Standard
If the same logic is used in 2 or more endpoints, it must be extracted to a Xano Function.
When to Create a Reusable Function
| Scenario | Action |
|---|---|
| Auth token check pattern | Built-in middleware (always use) |
| Permission/role check used in multiple APIs | Create Xano Function: check_workspace_permission |
| Creating a slug from a name | Create Xano Function: generate_slug |
| Sending an email via external API | Create Xano Function: send_email |
| Uploading a file to storage | Create Xano Function: upload_file |
| Formatting a date for display | Create Xano Function: format_date |
| Calculating a value used in multiple places | Create Xano Function: calculate_[name] |
Naming Standard for Xano Functions
verb_noun
| Good | Bad |
|---|---|
check_workspace_permission |
permissionCheck |
send_email_notification |
emailHelper |
generate_slug |
slugMaker |
calculate_invoice_total |
doCalc |
validate_phone_number |
phoneValidation |
Function Group Organization
Keep functions in organized groups:
Auth Functions
validate_token
get_auth_user
Permission Functions
check_workspace_permission
check_record_ownership
Notification Functions
send_email_notification
send_sms_notification
Utility Functions
generate_slug
format_date
calculate_discount
9. Database Table & Field Naming Standard
Follow the same naming conventions as Supabase.
Table Names
snake_case
plural
| Good | Bad |
|---|---|
projects |
Project |
project_members |
projectMember |
workspace_invitations |
inviteData |
Field Names
| Purpose | Standard |
|---|---|
| Primary key | id (integer auto-increment or UUID) |
| Timestamps | created_at, updated_at |
| Foreign key | user_id, project_id, workspace_id |
| Boolean | is_active, is_verified, has_access |
| Status | status with defined allowed values |
| Soft delete | deleted_at (nullable) |
Every Table Should Have
id — Primary key
created_at — Auto timestamp on create
updated_at — Auto timestamp on update
For user/workspace-scoped tables:
created_by_user_id — Who created the record
workspace_id — Which workspace owns it
10. Webhook Endpoint Standard
For webhooks from Stripe, SendGrid, Zoho, Smartlead, or any third party.
Webhook Requirements
Webhook Error Handling
If something fails during processing:
- Return
200to the provider (acknowledge receipt) - Log the failure internally
- Add to a retry queue if needed
Returning 500 to a webhook provider may cause it to retry repeatedly and flood your system.
11. Environment Variables Standard
| Variable | Usage |
|---|---|
| Database credentials | Always use Xano environment settings — never hardcode |
| External API keys (Stripe, SendGrid, OpenAI) | Store in Xano Environment Variables |
| Webhook secrets | Store in Xano Environment Variables |
| Supabase service role key (if used in Xano) | Store in Xano Environment Variables |
| JWT secret | Managed by Xano — do not expose |
Never hardcode API keys, passwords, or secrets inside Xano function logic.
12. API Documentation Standard
Every Xano API must be documented before frontend integration.
Use the API Documentation Template.
At minimum, document:
13. Xano — Definition of Done
An API built in Xano is complete only when: