Skip to main content
Workspaces (also called policies) are the foundation of team expense management in New Expensify. They provide centralized control over expense policies, member access, categories, approval workflows, and integrations—all while maintaining the flexibility to scale from small teams to large enterprises.

What is a Workspace?

A workspace is a shared environment where:
  • Team members submit and track expenses
  • Admins configure policies and approval rules
  • Approvers review and authorize expense reports
  • Accountants export data to accounting systems
  • Finance teams track spending and generate reports
Every workspace has its own chat rooms (#general, #admins, #announce) where team members can collaborate on expense-related discussions.

Workspace Types

New Expensify offers different workspace plans:

Free Plan

Perfect for individuals and small teams getting started:
  • Unlimited expense tracking
  • SmartScan receipt scanning
  • Basic expense categories
  • Manual expense approvals
  • Basic reporting
Free workspaces are ideal for personal expense tracking or small teams without complex approval needs.

Key Workspace Features

Member Management

Invite team members, assign roles, and manage permissions

Categories & Tags

Organize expenses with custom categories and multi-level tags

Approval Workflows

Configure single or multi-level approval chains

Policy Rules

Set expense limits, require receipts, and enforce compliance

Integrations

Connect to accounting systems and corporate card programs

Reporting

Generate reports and export data for analysis

Creating a Workspace

1

Start Creation

Click the + button in the app and select New Workspace.
2

Name Your Workspace

Enter a descriptive name (e.g., “Engineering Team”, “Acme Corp”).
3

Configure Settings

Set your workspace currency and default reimbursement method.
4

Invite Members

Add team members by email. They’ll receive invitations to join.

Workspace Creation Code

Here’s how workspaces are created programmatically:
// From src/libs/actions/Policy/Policy.ts
function createWorkspace(
    policyOwnerEmail: string,
    policyName: string,
    policyID?: string,
) {
    const workspaceName = policyName || CONST.POLICY.DEFAULT_WORKSPACE_NAME;
    
    const optimisticData: OnyxUpdate[] = [
        {
            onyxMethod: Onyx.METHOD.SET,
            key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
            value: {
                id: policyID,
                type: CONST.POLICY.TYPE.TEAM,
                name: workspaceName,
                role: CONST.POLICY.ROLE.ADMIN,
                owner: policyOwnerEmail,
                isPolicyExpenseChatEnabled: true,
                outputCurrency: CONST.CURRENCY.USD,
                pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
                employeeList: {
                    [policyOwnerEmail]: {
                        role: CONST.POLICY.ROLE.ADMIN,
                        errors: {},
                    },
                },
            },
        },
    ];
    
    const parameters: CreateWorkspaceParams = {
        policyID,
        announceChatReportID,
        adminsChatReportID,
        expenseChatReportID,
        ownerEmail: policyOwnerEmail,
        makeMeAdmin: false,
        policyName: workspaceName,
        type: CONST.POLICY.TYPE.TEAM,
    };
    
    API.write(
        WRITE_COMMANDS.CREATE_WORKSPACE,
        parameters,
        {optimisticData, successData, failureData}
    );
}
New Expensify automatically creates three workspace chat rooms when you create a workspace:
  • #announce: For important workspace-wide announcements
  • #admins: Private channel for workspace administrators
  • #general: Main discussion room for all members

Workspace Roles

Each workspace has a role-based permission system:

Admin

Full control over workspace settings:
// Check if user is workspace admin
function isPolicyAdmin(policy: OnyxEntry<Policy>): boolean {
    return policy?.role === CONST.POLICY.ROLE.ADMIN;
}
Permissions:
  • Configure all workspace settings
  • Manage members and roles
  • Set up approval workflows
  • Connect integrations
  • Export reports
  • Delete workspace

User

Standard member access:
function isPolicyMember(
    policyMembers: OnyxEntry<PolicyEmployeeList>,
    currentUserLogin: string,
): boolean {
    return Object.keys(policyMembers ?? {}).some(
        (email) => email === currentUserLogin
    );
}
Permissions:
  • Submit expenses
  • Create expense reports
  • Chat in workspace rooms
  • View workspace categories/tags
  • Submit for approval

Auditor

(Control Plan only) Permissions:
  • View all expenses and reports
  • Generate audit reports
  • Export data
  • Cannot submit or approve expenses

Workspace Architecture

Data Structure

Workspaces are stored in Onyx with this structure:
// Workspace data model
interface Policy {
    id: string;
    name: string;
    type: 'free' | 'team' | 'corporate';
    role: 'admin' | 'user' | 'auditor';
    owner: string;
    outputCurrency: string;
    
    // Features
    isPolicyExpenseChatEnabled: boolean;
    areWorkflowsEnabled: boolean;
    areCompanyCardsEnabled: boolean;
    
    // Settings
    employeeList: PolicyEmployeeList;
    categories: PolicyCategories;
    tags: PolicyTagLists;
    approvalMode: 'BASIC' | 'ADVANCED' | 'OPTIONAL';
    approver: string;
    
    // Integrations  
    connections: PolicyConnections;
    achAccount?: ACHAccount;
    
    // State
    pendingAction?: PendingAction;
    errors?: Errors;
}

Onyx Keys

// Workspace-related Onyx keys
ONYXKEYS.COLLECTION.POLICY // Main workspace data
ONYXKEYS.COLLECTION.POLICY_MEMBERS // Employee list
ONYXKEYS.COLLECTION.POLICY_CATEGORIES // Expense categories
ONYXKEYS.COLLECTION.POLICY_TAGS // Tags and tag lists
ONYXKEYS.COLLECTION.POLICY_REPORT_FIELDS // Custom report fields
ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID // Recently used

Workspace Settings

Configure your workspace through multiple settings pages:
  • Workspace name and avatar
  • Default currency
  • Workspace description
  • Fiscal year settings
  • Invite/remove members
  • Assign roles
  • View member activity
  • Bulk import from spreadsheet
  • Create expense categories
  • Set up tag hierarchies
  • Enable/disable items
  • Import from accounting system
  • Configure approval workflows
  • Set submission schedules
  • Auto-reporting settings
  • Payer configuration
  • Expense limits
  • Receipt requirements
  • Auto-approval thresholds
  • Prohibited expenses
  • Connect accounting software
  • Corporate card programs
  • Bank account setup
  • Export settings

Multi-Workspace Support

Users can belong to multiple workspaces:
// Switch between workspaces
function updateLastAccessedWorkspace(policyID: OnyxEntry<string>) {
    Onyx.set(ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, policyID ?? null);
}

// Get all policies user has access to
const allPolicies: OnyxCollection<Policy> = {};
Onyx.connect({
    key: ONYXKEYS.COLLECTION.POLICY,
    callback: (val, key) => {
        if (!key) return;
        if (val === null || val === undefined) {
            delete allPolicies[key];
            return;
        }
        allPolicies[key] = val;
    },
});
Switch workspaces using the workspace selector in the top navigation. Your most recently accessed workspace is remembered.

Best Practices

Begin with basic categories and rules. Add complexity as your team grows and you identify specific needs.
Name workspaces clearly (“Marketing Team” not “Workspace 1”). This helps when users belong to multiple workspaces.
Configure approval workflows before team members start submitting expenses to avoid confusion.
Review workspace settings quarterly to remove inactive members and update outdated categories.
Connect your accounting system early to streamline month-end closing and reduce manual data entry.

Next Steps

Workspace Settings

Configure workspace name, currency, and general settings

Member Management

Invite team members and assign roles

Categories & Tags

Set up expense organization and tracking

Rules & Workflows

Configure approval flows and policy rules

Build docs developers (and LLMs) love