Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Welcome to the Expensabl documentation! Expensabl is an expense management automation tool living right in your browser.

What is Expensabl?

Expensabl is a Chrome extension designed to automate expense management on the Navan platform. It streamlines the expense creation process by eliminating manual data entry and providing intelligent automation features.

Core Capabilities

  • Automatic Token Capture: Seamlessly captures authentication tokens when you log into Navan
  • Smart Templates: Create reusable templates for recurring expenses with variable substitution
  • Scheduled Automation: Set up recurring expenses that create themselves automatically
  • Persistent Side Panel: Always-available interface that stays open across browser tabs
  • Enterprise-Ready: Built with security, reliability, and performance in mind

Architecture Overview

Expensabl follows a layered architecture with clear separation of concerns:

Chrome Extension Layer

  • Service Worker: Handles background tasks, message routing, and token capture
  • Content Script: Injected into Navan pages for seamless token interception
  • Side Panel UI: Persistent interface for expense management
  • Message Adapter: Type-safe communication between extension contexts

Features Layer

  • Authentication: Secure token management with validation and refresh
  • Expenses: Complete expense lifecycle management with retry logic
  • Messaging: Robust message routing with handler pattern
  • Templates: Sophisticated template engine with scheduling capabilities

Shared Services

  • Logger: Environment-aware logging with Chrome storage integration
  • Storage: Abstracted Chrome storage with transaction support
  • Types: Shared TypeScript interfaces ensuring type safety

Key Benefits

For End Users

  • Time Savings: Reduce expense creation time by up to 90% with templates
  • Never Forget: Scheduled expenses ensure recurring costs are always captured
  • Consistency: Templates ensure expenses follow company policies
  • Convenience: Side panel stays open while you work

For Organizations

  • Compliance: Consistent expense data following company policies
  • Visibility: All expenses captured on time for better financial tracking
  • Efficiency: Reduced administrative overhead for expense management
  • Integration: Seamless integration with existing Navan workflows

Documentation Structure

This documentation is organized to serve different audiences:

User Guide

Step-by-step instructions for using Expensabl:

  • Installation and setup
  • Creating and managing expenses
  • Working with templates
  • Setting up schedules

Developer Guide

Technical documentation for contributors:

  • Architecture deep dive
  • Development environment setup
  • Building and testing
  • Contributing guidelines

API Reference

Detailed API documentation:

  • Message API for extension communication
  • Storage API for data persistence
  • Expense API for Navan integration

Getting Started

For Users

  1. Install the extension from the Chrome Web Store
  2. Navigate to Navan and sign in
  3. Open the Expensabl side panel
  4. Start creating expenses with templates!

For Developers

  1. Clone the repository
  2. Install dependencies with npm install
  3. Build with npm run build:dev
  4. Load unpacked extension in Chrome

For detailed instructions, see the Getting Started guide.

Getting Started

This guide will help you get up and running with Expensabl quickly.

Prerequisites

For Users

  • Google Chrome browser (version 119 or later)
  • A Navan account with expense creation permissions

For Developers

  • Node.js (v16 or higher)
  • npm (v7 or higher)
  • Git

Installation Options

Option 1: Chrome Web Store (Coming Soon)

  1. Visit the Chrome Web Store
  2. Search for "Expensabl"
  3. Click "Add to Chrome"
  4. Grant the required permissions

Option 2: Development Build

Clone and Install

# Clone the repository
git clone https://github.com/xtendabl/expensabl.git
cd expensabl

# Install dependencies
npm install

# Build for development (includes source maps)
npm run build:dev

# Or build for production (optimized)
npm run build

Load in Chrome

  1. Open Chrome Extension Management

    • Navigate to chrome://extensions/ in your Chrome browser
    • Or click the puzzle icon in the toolbar → "Manage Extensions"
  2. Enable Developer Mode

    • Toggle the "Developer mode" switch in the top right corner
  3. Load the Extension

    • Click "Load unpacked" button
    • Navigate to your expensabl/dist directory
    • Select the folder and click "Open"
  4. Verify Installation

    • The extension should appear in your extensions list
    • Look for the Expensabl icon in your Chrome toolbar
    • If not visible, click the puzzle icon and pin Expensabl

First Time Setup

1. Sign in to Navan

  • Navigate to app.navan.com
  • Sign in with your corporate credentials
  • The extension will automatically capture your authentication token
  • You'll see a notification when the token is captured successfully

2. Open the Side Panel

There are several ways to access Expensabl:

Method 1: Extension Icon

  • Click the Expensabl icon in the Chrome toolbar
  • The side panel will open automatically

Method 2: Extensions Menu

  • Click the Extensions puzzle icon
  • Find Expensabl in the list
  • Click "Open side panel"

Method 3: Chrome Menu

  • Click the three-dot menu in Chrome
  • Go to "More tools" → "Extensions"
  • Find Expensabl and click "Open side panel"

3. Initial Configuration

When you first open Expensabl:

  1. Help Section: Review the built-in help guide
  2. Permissions: Grant any additional permissions if prompted
  3. Preferences: Set your default expense preferences

Creating Your First Expense

Manual Creation

  1. In the side panel, click "Fetch Expenses" to load your recent expenses
  2. Click "Create New Expense" button
  3. Fill in the required fields:
    • Merchant name
    • Amount and currency
    • Date
    • Category/Policy
    • Description (optional)
  4. Click "Submit Expense"

From a Template

  1. Navigate to the Templates section
  2. Click "Apply" on any template
  3. Review and modify the pre-filled data
  4. Submit the expense

Development Workflow

If you're developing or customizing Expensabl:

Making Changes

  1. Edit Source Files: Make changes in the src/ directory
  2. Rebuild: Run npm run build:dev to rebuild with your changes
  3. Reload Extension:
    • Go to chrome://extensions/
    • Find Expensabl and click the refresh icon
    • Or use Cmd+R (Mac) / Ctrl+R (Windows/Linux) on the extensions page
  4. Test Changes: Open the extension and verify your changes

Available Commands

# Development build with source maps
npm run build:dev

# Production build (optimized)
npm run build

# Watch mode (auto-rebuild on changes)
npm run watch

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Fix linting issues
npm run lint:fix

# Fix all formatting
npm run format:fix

# Clean build artifacts
npm run clean

Debugging Tips

Background Service Worker:

  • Click "Inspect views: service worker" on the extension card in chrome://extensions/
  • This opens DevTools for background script debugging

Side Panel UI:

  • Right-click the extension side panel and select "Inspect"
  • This opens DevTools for UI debugging

Content Scripts:

  • Open DevTools on any Navan page
  • Content script logs appear in the page's console

Troubleshooting

Extension Not Loading

  • Ensure you're in Developer Mode
  • Check that the dist/ folder exists and contains manifest.json
  • Try rebuilding with npm run build:dev

Token Not Captured

  • Make sure you're signed into Navan
  • Refresh the Navan page after installing the extension
  • Check the service worker console for errors

Side Panel Not Opening

  • Ensure Chrome version is 119 or later
  • Try unpinning and re-pinning the extension
  • Restart Chrome if necessary

Next Steps

Now that you have Expensabl running:

For developers:

Installation

Core Activities

This guide explains the three core activities that power Expensabl: Token Interception, Expense Creation, and Scheduled Execution.

Quick Reference

ActivityTriggerKey ComponentsChrome APIs Used
Token InterceptionUser login to NavanContent Script, Service WorkerwebRequest, storage
Expense CreationTemplate selection/Manual entryUI Components, Expense Servicestorage, runtime
Scheduled ExecutionChrome alarmsScheduler, Template Servicealarms, storage, notifications
ActivityPrerequisitesData FlowStorage Output
Token InterceptionActive Navan sessionHTTP Headers → Content Script → Service WorkerEncrypted auth token
Expense CreationValid auth token, Template dataUI → Message Router → API → StorageExpense record, Template usage stats
Scheduled ExecutionActive template with scheduleAlarm → Service Worker → APIExecution history, Created expense

Token Interception

The extension automatically captures authentication tokens when users log into Navan, eliminating the need for manual credential entry. This foundational activity enables all other features by establishing secure API access.

How It Works

  1. Content Script Monitoring: The content script monitors network requests on Navan domains
  2. Multiple Capture Strategies: Uses various techniques to ensure reliable token capture
  3. Secure Storage: Tokens are encrypted and stored in Chrome's local storage
  4. Automatic Validation: Validates captured tokens before storage

Token Capture Flow

graph LR
    A[User Login] --> B[Navan Auth]
    B --> C[API Call with Token]
    C --> D[Content Script Intercepts]
    D --> E[Token Captured Message]
    E --> F[Service Worker]
    F --> G[Encrypted Token]
    G --> H[Storage]

Implementation Details

The token capture system employs a multi-layered approach:

  • Network Interception: Monitors fetch and XMLHttpRequest calls
  • Header Extraction: Captures Authorization headers from API requests
  • Validation: Ensures token format is correct before storage
  • Refresh Detection: Automatically updates stored tokens when refreshed

Security Considerations

  • Tokens are never logged or exposed in console
  • All tokens are encrypted before storage
  • Token scope is limited to expense operations
  • Automatic cleanup of expired tokens

Expenses and Templates

The expense and template system forms the core of user interaction, enabling both one-time expense creation and reusable template management.

Bi-directional Workflow

Users can:

  1. Create expenses from templates: Apply saved templates to quickly create new expenses
  2. Convert expenses to templates: Save any expense as a template for future use

Template Features

Template Storage

  • Essential expense information without transaction-specific details
  • Usage statistics and execution history tracking
  • Support for variable substitution (e.g., {month}, {year})
  • 5-template limit per user for optimal performance

Template Management

  • Create: Save new templates from scratch or existing expenses
  • Edit: In-place editing with validation
  • Apply: Generate expenses with pre-filled data
  • Delete: Remove unused templates with confirmation

Real-World Use Cases

Weekly Team Lunch Template

Name: "Friday Team Lunch"
Merchant: "Local Bistro"
Amount: $125.00
Category: "Meals - Team"
Schedule: Weekly (Fridays)
Notes: "Weekly team building lunch"

Monthly Software Subscription

Name: "Design Software License"
Merchant: "Adobe Creative Cloud"
Amount: $52.99
Category: "Software - Subscription"
Schedule: Monthly (1st of month)
Project: "Marketing Dept"

Client Entertainment Template

Name: "Client Dinner Template"
Merchant: "[To be filled]"
Amount: $200.00
Category: "Entertainment - Client"
Schedule: Manual (no automation)
Notes: "Standard client dinner budget"

Template Data Lifecycle

  1. Creation: User defines template parameters
  2. Storage: Template saved to Chrome sync storage
  3. Usage: Template applied to create expenses
  4. Updates: Usage count and last-used timestamp updated
  5. Sync: Templates synchronized across devices

Scheduled Executions

Scheduled executions transform manual expense entry into an automated workflow, leveraging Chrome's alarm API to create expenses at predetermined intervals.

Supported Schedule Types

  • Daily: Every day at a specific time
  • Weekly: Specific day(s) of the week
  • Monthly: Specific day of the month
  • Custom: User-defined intervals

Scheduling Timeline Example

gantt
    title Template Execution Timeline
    dateFormat YYYY-MM-DD
    axisFormat %b %d
    
    section Daily Template
    Parking (9 AM)     :active, d1, 2025-01-06, 1d
    Parking (9 AM)     :active, d2, 2025-01-07, 1d
    Parking (9 AM)     :active, d3, 2025-01-08, 1d
    Parking (9 AM)     :active, d4, 2025-01-09, 1d
    Parking (9 AM)     :active, d5, 2025-01-10, 1d
    
    section Weekly Template
    Team Lunch (Fri)   :active, w1, 2025-01-10, 1d
    Team Lunch (Fri)   :active, w2, 2025-01-17, 1d
    
    section Monthly Template
    Software (1st)     :active, m1, 2025-01-01, 1d
    Software (1st)     :active, m2, 2025-02-01, 1d

Chrome Alarm Configuration

The scheduling engine:

  • Calculates optimal execution times based on user timezone
  • Persists across browser restarts
  • Monitors execution history for failure detection
  • Supports pause/resume functionality

Execution Process

  1. Alarm Trigger: Chrome alarm fires at scheduled time
  2. Template Retrieval: Fetch template data from storage
  3. Variable Substitution: Replace placeholders with current values
  4. Expense Creation: Submit expense via API
  5. History Update: Log execution result
  6. Next Schedule: Calculate and set next execution time

Error Handling

  • Retry Logic: Automatic retry on network failures
  • Notification: User notified of persistent failures
  • Fallback: Manual intervention option for critical expenses
  • Recovery: Automatic recovery after connection restored

Real-World Scheduling Examples

Daily Parking Expense

Template: "Office Parking"
Amount: $15.00
Schedule: Daily (Weekdays only)
Time: 9:00 AM
Auto-submit: Yes
Note: Automatically creates parking expenses for work days

Bi-weekly Client Dinner

Template: "Client Entertainment - Dinner"
Amount: $250.00
Schedule: Every 2 weeks (Thursday)
Time: 6:00 PM
Auto-submit: No (requires receipt)
Note: Reminder for regular client relationship building

Integration Points

Service Worker

  • Central hub for all background operations
  • Manages alarms and scheduled executions
  • Handles API communication
  • Processes messages between contexts

Content Script

  • Injected into Navan pages
  • Monitors for authentication tokens
  • Minimal footprint for performance

Side Panel UI

  • User interface for all interactions
  • Real-time updates via message passing
  • Template and schedule management
  • Expense review and submission

Best Practices

For Token Management

  • Let the extension handle token capture automatically
  • Don't manually enter tokens
  • Sign out and back in if token issues occur

For Templates

  • Use descriptive names for easy identification
  • Include variable placeholders for dynamic content
  • Review and update templates periodically
  • Delete unused templates to stay under the limit

For Scheduling

  • Set schedules based on your timezone
  • Use appropriate frequencies for expense types
  • Monitor execution history regularly
  • Pause schedules during vacations or breaks

Troubleshooting

Token Not Captured

  1. Ensure you're signed into Navan
  2. Refresh the page after extension installation
  3. Check service worker logs for errors
  4. Try signing out and back in

Template Not Saving

  1. Check template limit (max 5)
  2. Verify all required fields are filled
  3. Ensure Chrome sync is enabled
  4. Check storage quota in Chrome

Schedule Not Executing

  1. Verify Chrome is running at scheduled time
  2. Check alarm permissions in manifest
  3. Review execution history for errors
  4. Ensure template is not paused

Configuration

Usage

Authentication

Creating Expenses

Templates

Scheduling

Architecture Overview

Project Structure

This guide provides a comprehensive overview of the Expensabl project structure, explaining how different components fit together to create a cohesive Chrome extension.

Directory Overview

expensabl/
├── src/                    # Source code
│   ├── chrome/            # Chrome extension layer
│   ├── features/          # Core business logic
│   └── shared/            # Shared services and utilities
├── public/                # Static assets
├── docs/                  # Documentation
├── dist/                  # Build output (generated)
├── tests/                 # Test files
└── [config files]         # Configuration files

Chrome Extension Layer (src/chrome/)

The Chrome extension layer serves as the primary interface between users and the expense management system. It handles all UI rendering, user interactions, and communication with Chrome's extension APIs.

DirectoryPurposeHow It Fits Into The System
components/Reusable UI componentsProvides the building blocks for the extension's user interface, implementing a component-based architecture that ensures consistent look and feel across all views. These components handle user interactions and communicate with the background service worker through the messaging system.
domains/expenses/Expense-specific UI domainActs as the presentation layer for expense management, maintaining local UI state and orchestrating the display of expense data. It bridges the gap between raw expense data from the features layer and the visual components users interact with.
shared/Shared UI servicesProvides critical infrastructure for UI operations including state management for reactive updates and a messaging facade that abstracts Chrome's extension messaging API. This layer ensures UI components can communicate with background services without knowing implementation details.
builders/UI content buildersDynamically generates UI content based on user context and application state, reducing the need for static templates. This approach allows for more flexible and maintainable UI generation, particularly for help content and dynamic forms.
Root filesExtension entry pointsThese files serve as the primary integration points with Chrome's extension APIs. The service worker handles background tasks and API calls, the content script injects functionality into web pages, and the sidepanel provides the main user interface for expense management.

Key Files in Chrome Layer

  • service-worker.ts: Background script handling message routing and token capture
  • content.ts: Injected into Navan pages for token interception
  • sidepanel.ts: Main UI entry point for the side panel
  • message-adapter.ts: Type-safe messaging wrapper

Features - Core Business Logic (src/features/)

The features directory implements Domain-Driven Design principles, organizing code by business capability rather than technical layers. Each subdomain encapsulates its complete business logic, making the system more maintainable and scalable.

DirectoryPurposeHow It Fits Into The System
auth/Authentication managementManages the complete authentication lifecycle including token storage, validation, and refresh. It ensures secure access to the expense API and maintains user sessions across browser restarts, acting as the gatekeeper for all authenticated operations.
expenses/Expense domain logicThe heart of the application's business logic, handling all expense-related operations from creation to submission. It includes sophisticated data transformation layers, retry mechanisms for network failures, and maintains consistency between local and remote expense data.
messaging/Message routing systemImplements a robust message-based architecture that enables communication between different extension contexts (content script, service worker, sidepanel). It uses a handler pattern with type safety to ensure reliable command execution and response handling across the extension.
templates/Template managementEnables expense automation through reusable templates with sophisticated scheduling capabilities. This module handles complex time calculations, validates scheduling rules, and integrates with the expense creation system to automatically generate expenses based on user-defined patterns.

Feature Module Structure

Each feature module typically contains:

  • types.ts: TypeScript interfaces and types
  • service.ts: Business logic implementation
  • repository.ts: Data access layer
  • handlers/: Message handlers for the module
  • utils.ts: Helper functions specific to the feature

Shared Services (src/shared/)

The shared services layer provides cross-cutting concerns and utilities used throughout the application. These services abstract complex operations and provide consistent interfaces for common functionality.

DirectoryPurposeHow It Fits Into The System
services/logger/Logging infrastructureProvides environment-aware logging that adapts between development and production modes. It integrates with Chrome's storage API to persist logs for debugging while respecting performance constraints, making it easier to diagnose issues in production.
services/storage/Storage abstractionAbstracts Chrome's storage APIs behind a consistent interface, supporting both synchronous and asynchronous operations. It includes transaction support for atomic updates and caching mechanisms to improve performance while maintaining data consistency.
types/Common type definitionsEstablishes the contract between different parts of the system through shared TypeScript interfaces. This ensures type safety across module boundaries and makes refactoring safer by catching breaking changes at compile time.

Shared Service Patterns

  • Singleton Pattern: Services export pre-configured instances
  • Adapter Pattern: Abstract Chrome APIs behind consistent interfaces
  • Factory Pattern: Create context-specific service instances

Public Assets (public/)

Contains all static resources required by the Chrome extension, including visual assets and the manifest that defines the extension's capabilities.

Directory/FilePurposeHow It Fits Into The System
icons/Extension iconsProvides visual identity for the extension across different Chrome UI surfaces, following Google's design guidelines for extensions. Multiple sizes ensure crisp display on various screen densities.
manifest.jsonChrome extension manifestDefines the extension's capabilities, permissions, and integration points with Chrome. This configuration determines what APIs the extension can access and how it appears to users in the Chrome Web Store and browser UI.

Manifest V3 Permissions

Key permissions required:

  • storage: Store user data and preferences
  • tabs: Access tab information
  • activeTab: Interact with active tab
  • sidePanel: Display side panel UI
  • webRequest: Monitor network requests
  • notifications: Show system notifications
  • alarms: Schedule recurring tasks
  • host permission: https://app.navan.com/*

Documentation (docs/)

Project documentation that helps maintain consistency and knowledge sharing across the development team.

ContentPurposeHow It Fits Into The System
src/Source documentationContains the mdBook source files including guides, API references, and architectural documentation. These files are compiled into the static documentation site.
book/Built documentationThe compiled static site generated from the source files. This can be served locally or deployed to GitHub Pages for easy access by team members and users.

Configuration Files

Root-level configuration files that define how the project is built, tested, and maintained.

FilePurposeHow It Fits Into The System
webpack.config.jsBuild configurationOrchestrates the build process, handling TypeScript compilation, code splitting for different extension contexts, and optimization for production. It ensures the extension loads quickly while maintaining development ergonomics.
jest.config.jsTest configurationConfigures the testing environment to work with Chrome extension APIs and TypeScript. It sets up mocks for browser APIs and ensures tests run in an environment that closely matches the extension's runtime.
tsconfig.jsonTypeScript configurationDefines compilation rules and module resolution strategies that enable clean imports and strong type checking. The path aliases defined here improve code organization and make imports more maintainable.
package.jsonDependencies and scriptsCentral configuration for the project's dependencies and automation scripts. It defines the project's external dependencies carefully chosen for bundle size and compatibility with the extension environment.

Build Output (dist/)

Generated during the build process, this directory contains:

  • manifest.json: Processed extension manifest
  • service-worker.js: Bundled background script
  • content.js: Bundled content script
  • sidepanel.html: Side panel HTML entry
  • sidepanel.js: Bundled side panel code
  • assets/: Icons and other static resources

Development Patterns

Message Flow

graph LR
    A[User Action] --> B[UI Component]
    B --> C[Message]
    C --> D[Router]
    D --> E[Handler]
    E --> F[Service]
    F --> G[Storage/API]
    G --> H[Response]
    H --> I[UI Update]

Data Flow

graph LR
    A[Navan API] --> B[Token Capture]
    B --> C[Storage]
    C --> D[Template/Expense Service]
    D --> E[UI]
    E --> F[User Action]
    F --> G[Chrome Sync]
    G --> C

Module Dependencies

  • UI layer depends on features and shared services
  • Features depend on shared services
  • Shared services have no dependencies on other layers
  • All layers use shared types

Best Practices

Code Organization

  1. Keep related code together in feature modules
  2. Use index.ts files for clean exports
  3. Separate types from implementation
  4. Follow consistent naming conventions

Dependency Management

  1. Minimize external dependencies
  2. Use path aliases for clean imports
  3. Avoid circular dependencies
  4. Keep bundle size small

Testing Structure

  1. Mirror source structure in tests
  2. Unit tests next to source files
  3. Integration tests in separate directory
  4. Mock Chrome APIs consistently

Documentation

  1. Keep docs close to code
  2. Update docs with code changes
  3. Use JSDoc for complex functions
  4. Maintain architectural decision records

Development Setup

Building and Testing

Contributing

Message API

Storage API

Expense API

JSON Data Structures Reference

This document provides a comprehensive reference for all JSON data structures used in the Expensabl Chrome extension, with examples of actual objects and their relationships.

Table of Contents

  1. Expense Data Structures
  2. Template Data Structures
  3. Authentication Structures
  4. Message Types
  5. Storage Structures
  6. Error Structures

Expense Data Structures

ExpenseCreatePayload - Request to Create New Expense

{
  "merchant": "Office Depot",
  "amount": 45.99,
  "currency": "USD",
  "date": "2025-08-01",
  "policy": "OFFICE_SUPPLIES",
  "description": "Printer paper and pens for Q3",
  "project": "Marketing-2025",
  "customFields": {
    "costCenter": "MKT-100",
    "clientCode": "INTERNAL"
  }
}

Expense - Full Expense Object

{
  "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "dateCreated": "2025-08-01T14:30:00.000Z",
  "dateModified": "2025-08-01T14:45:00.000Z",
  "dateSubmitted": null,
  "dateApproved": null,
  "status": "DRAFT",
  "source": "MANUAL",
  "user": {
    "uuid": "user-123",
    "email": "user@company.com",
    "givenName": "John",
    "familyName": "Doe",
    "fullName": "John Doe"
  },
  "merchant": {
    "uuid": "merchant-456",
    "name": "Office Depot",
    "category": "office_supplies_and_stationery",
    "categoryGroup": "OFFICE_SUPPLIES",
    "logo": "https://example.com/logos/office-depot.png"
  },
  "amount": 45.99,
  "currency": "USD",
  "accountAmount": 45.99,
  "accountCurrency": "USD",
  "merchantAmount": 45.99,
  "merchantCurrency": "USD",
  "date": "2025-08-01",
  "instant": "2025-08-01T14:30:00.000Z",
  "policy": "OFFICE_SUPPLIES",
  "policyName": "Office Supplies",
  "details": {
    "description": "Printer paper and pens for Q3",
    "project": "Marketing-2025",
    "participants": ["user-123"],
    "customFieldValues": [
      {
        "fieldId": "field-1",
        "fieldName": "Cost Center",
        "value": "MKT-100"
      }
    ],
    "glCode": {
      "uuid": "gl-789",
      "number": "6100",
      "name": "Office Supplies"
    }
  },
  "receiptRequired": false,
  "receiptKey": null,
  "flagged": false,
  "flag": {
    "status": null,
    "reasons": {},
    "reasonList": []
  },
  "reimbursementMethod": "PAYROLL",
  "reportingData": {
    "department": "Marketing",
    "billTo": "Corporate",
    "region": "North America"
  }
}

ExpenseListResponse - Paginated Expense List

{
  "expenses": [
    {
      "uuid": "expense-1",
      "merchant": "Starbucks",
      "amount": 12.50,
      "date": "2025-08-01",
      "status": "APPROVED"
    },
    {
      "uuid": "expense-2", 
      "merchant": "Uber",
      "amount": 28.75,
      "date": "2025-07-31",
      "status": "PENDING"
    }
  ],
  "total": 156,
  "page": 1,
  "pageSize": 20,
  "hasMore": true
}

SearchTransaction - Search Result Item

{
  "uuid": "txn-123",
  "type": "expense",
  "merchantName": "Amazon",
  "amount": 89.99,
  "currency": "USD",
  "date": "2025-08-01",
  "status": "DRAFT",
  "policyName": "Technology",
  "description": "USB-C adapters",
  "highlightedFields": {
    "merchantName": "<em>Amazon</em> Web Services"
  }
}

Template Data Structures

ExpenseTemplate - Complete Template Object

{
  "id": "template-123",
  "name": "Monthly Phone Bill",
  "description": "Verizon monthly service charge",
  "createdAt": "2025-07-01T10:00:00.000Z",
  "lastModified": "2025-08-01T14:30:00.000Z",
  "metadata": {
    "usageCount": 7,
    "lastUsed": "2025-08-01T09:00:00.000Z",
    "isFavorite": true,
    "tags": ["recurring", "utilities"],
    "version": 1
  },
  "expenseData": {
    "merchant": "Verizon",
    "amount": 85.00,
    "currency": "USD",
    "policy": "PHONE",
    "description": "Phone service - {month} {year}",
    "project": "Operations",
    "categoryGroup": "PHONE"
  },
  "scheduling": {
    "enabled": true,
    "frequency": "monthly",
    "interval": 1,
    "dayOfMonth": 15,
    "startTime": "09:00",
    "timezone": "America/New_York",
    "nextExecution": "2025-09-15T13:00:00.000Z",
    "endDate": null
  },
  "executionHistory": [
    {
      "id": "exec-456",
      "executedAt": "2025-08-15T13:00:05.000Z",
      "success": true,
      "expenseId": "expense-789",
      "error": null,
      "duration": 1250
    }
  ]
}

CreateTemplateRequest

{
  "name": "Client Lunch Template",
  "description": "Standard client lunch expense",
  "expenseData": {
    "merchant": "Restaurant (Variable)",
    "amount": 75.00,
    "currency": "USD",
    "policy": "MEALS_CLIENT",
    "description": "Client lunch - {client_name}"
  },
  "isFavorite": false
}

TemplateExecution - Execution History Entry

{
  "id": "exec-123",
  "templateId": "template-456",
  "executedAt": "2025-08-01T12:00:00.000Z",
  "success": true,
  "expenseId": "expense-789",
  "expenseData": {
    "merchant": "Verizon",
    "amount": 85.00,
    "description": "Phone service - August 2025"
  },
  "error": null,
  "duration": 1523,
  "retryCount": 0
}

Authentication Structures

TokenData - Stored Authentication Token

{
  "token": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expiresAt": 1753396268728,
  "refreshToken": "refresh_token_value",
  "tokenType": "Bearer",
  "scope": "expenses:read expenses:write",
  "metadata": {
    "userId": "user-123",
    "companyId": "company-456",
    "capturedAt": "2025-08-01T10:00:00.000Z",
    "source": "login",
    "lastValidated": "2025-08-01T14:00:00.000Z"
  }
}

Message Types

BackgroundMessage Examples

Token Captured Message

{
  "action": "TOKEN_CAPTURED",
  "data": {
    "token": "Bearer eyJhbGciOiJIUzI1NiIs...",
    "source": "fetch",
    "timestamp": 1753309868728
  }
}

Create Expense Message

{
  "action": "CREATE_EXPENSE",
  "data": {
    "merchant": "Uber",
    "amount": 28.50,
    "currency": "USD",
    "date": "2025-08-01",
    "policy": "TRANSPORTATION"
  }
}

Execute Template Message

{
  "action": "EXECUTE_TEMPLATE",
  "data": {
    "templateId": "template-123",
    "variables": {
      "month": "August",
      "year": "2025"
    }
  }
}

MessageResponse

{
  "success": true,
  "data": {
    "expenseId": "expense-123",
    "status": "CREATED"
  },
  "error": null,
  "timestamp": 1753309868728
}

Storage Structures

Storage Keys and Data Types

KeyTypeExample Data
auth_tokenTokenDataSee TokenData structure above
templatesMap<string, ExpenseTemplate>Template objects indexed by ID
recent_expensesExpense[]Array of recent expense objects
user_preferencesObject{"theme": "light", "notifications": true}
execution_logTemplateExecution[]Array of execution history
pending_schedulesObject{"template-123": "2025-09-15T13:00:00.000Z"}

Transaction Storage Example

{
  "transactionId": "txn-789",
  "operations": [
    {
      "type": "set",
      "key": "template-123",
      "value": { "...template data..." },
      "timestamp": 1753309868728
    },
    {
      "type": "remove",
      "key": "template-old",
      "timestamp": 1753309868729
    }
  ],
  "status": "pending",
  "createdAt": "2025-08-01T14:30:00.000Z"
}

Error Structures

ApiError Response

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid expense data",
    "details": {
      "field": "amount",
      "reason": "Amount must be greater than 0"
    },
    "timestamp": "2025-08-01T14:30:00.000Z",
    "requestId": "req-123"
  }
}

TemplateError

{
  "code": "TEMPLATE_NOT_FOUND",
  "message": "Template with ID 'template-999' not found",
  "templateId": "template-999",
  "timestamp": "2025-08-01T14:30:00.000Z"
}

Chrome Alarm Metadata

{
  "alarm_template_123": {
    "templateId": "template-123",
    "created": "2025-08-01T10:00:00.000Z",
    "nextExecution": "2025-09-15T13:00:00.000Z",
    "frequency": "monthly",
    "retryCount": 0,
    "lastError": null
  }
}

Policy and Validation Structures

PolicyDescription

{
  "type": "MEALS_CLIENT",
  "name": "Client Meals",
  "description": "Meals with clients and prospects",
  "picture": "https://example.com/icons/meals.png",
  "warningAmounts": {
    "DAILY": {
      "USD": 150,
      "EUR": 130,
      "GBP": 120
    }
  },
  "requiresReceipt": true,
  "requiresParticipants": true,
  "glCodeRequired": true
}

Custom Field Structures

{
  "customFields": [
    {
      "id": "field-1",
      "name": "Cost Center",
      "type": "select",
      "required": true,
      "options": ["MKT-100", "ENG-200", "OPS-300"],
      "value": "MKT-100"
    },
    {
      "id": "field-2",
      "name": "Project Code",
      "type": "text",
      "required": false,
      "value": "PROJ-2025-08"
    }
  ]
}

Changelog