# Figa Help: complete documentation Generated from the same articles as the Help website. For a smaller context, use https://getfiga.com/help/llms.txt and read only the linked guides you need. Source: https://getfiga.com/help/ Help center # Help for every bill, and every month ahead. Guides for planning recurring bills and installments in Figa, marking them paid, sharing a workspace and connecting AI assistants. Start here ## New to Figa? Three short reads. [How Figa works. Workspaces, bills, schedules and the months ahead, in one page.](https://getfiga.com/help/how-figa-works) [Your first month in 10 minutes. Add rent and a few recurring bills, then see what this month needs.](https://getfiga.com/help/getting-started) [Free or Pro?. What Free covers, what Pro adds, and when it is worth it.](https://getfiga.com/help/free-or-pro) Browse by topic ## Everything Figa does, explained. ### Getting started The ideas behind Figa and your first month. - [How Figa works](https://getfiga.com/help/how-figa-works) - [Your first month](https://getfiga.com/help/getting-started) - [Language and region](https://getfiga.com/help/preferences) ### Plan your bills Recurring bills, installments, services and forecasts. - [Recurring bills](https://getfiga.com/help/recurring-bills) - [Installments](https://getfiga.com/help/installments) - [Variable bills and forecasts](https://getfiga.com/help/bill-forecasts) - [Services per visit](https://getfiga.com/help/services) - [Pause or end a series](https://getfiga.com/help/pause-resume-end) ### Payments and reminders Mark bills paid and stay ahead of due dates. - [Mark bills paid](https://getfiga.com/help/mark-paid) - [Reminders and notifications](https://getfiga.com/help/notifications) ### Organize Categories, recipients, tags and currencies. - [Categories](https://getfiga.com/help/categories) - [Recipients](https://getfiga.com/help/recipients) - [Tags](https://getfiga.com/help/tags) - [Multiple currencies](https://getfiga.com/help/currencies) ### See your money Months ahead, insights and price history. - [Dashboard](https://getfiga.com/help/dashboard) - [Insights](https://getfiga.com/help/insights) - [Amount history](https://getfiga.com/help/amount-history) ### Share and manage Workspaces, people, roles and history. - [Workspaces](https://getfiga.com/help/workspaces) - [Members and roles Pro](https://getfiga.com/help/members-and-roles) - [Change history](https://getfiga.com/help/change-history) ### Import and export Bring your bills in, take your data out. - [Import from CSV Pro](https://getfiga.com/help/import-csv) - [Export your data](https://getfiga.com/help/export) - [Delete your account](https://getfiga.com/help/delete-account) ### Plans and billing Free or Pro, changing plans and refunds. - [Free or Pro?](https://getfiga.com/help/free-or-pro) - [Change or cancel your plan](https://getfiga.com/help/billing) ### AI and automations Connect an assistant, a script or a workflow. - [Connect AI and tools](https://getfiga.com/help/automations) Developers and AI ## Connect an assistant, a script or a workflow. This Help is readable by agents too: every guide has a [Markdown version](https://getfiga.com/help/for-agents), listed in [llms.txt](https://getfiga.com/help/llms.txt). [View this page as Markdown](https://getfiga.com/help/raw/index.md). - [Connect with MCP Claude, ChatGPT and other remote MCP clients](https://getfiga.com/help/developers/mcp) - [REST API Keys, expenses, schedules and payments](https://getfiga.com/help/developers/api) - [Keep bills current from invoices A workflow from inbox to confirmed amount](https://getfiga.com/help/developers/invoice-workflow) - [Agent skills Ready-made workflows for your agent](https://getfiga.com/help/developers/agent-skills) - [Zapier and n8n No-code automations](https://getfiga.com/help/developers/integrations/zapier) - [Raycast Figa from your keyboard](https://getfiga.com/help/developers/integrations/raycast) Still stuck? Write to us, a person reads every message. [contact@getfiga.com](mailto:contact@getfiga.com) --- Source: https://getfiga.com/help/how-figa-works/ # How Figa works Workspaces, expenses, recurring series and the months ahead: the few ideas behind Figa. Figa plans the bills you know will come: rent, utilities, subscriptions, installments and yearly renewals. You add each bill once with its schedule, and every month, past and coming, shows what it needs, what is paid and what is still to pay. Figa never connects to a bank. ## Workspaces hold your bills A **workspace** is one set of bills: your home, your business or a project. Each workspace has its own expenses, categories, recipients, tags, members and connections, and one **base currency** that every total is shown in. The base currency is chosen when you create the workspace and cannot be changed later. Workspaces belong to an **organization**. The organization's plan, Free or Pro, applies to all of its workspaces. See [Workspaces](https://getfiga.com/help/workspaces). ## An expense is one-time or recurring - **One-time**: a single cost on one date, like a repair or a ticket. - **Recurring**: a series with a schedule, like rent on the 1st of every month. Figa creates one **occurrence** for each date, so each month lists the bills due in it. You can change one occurrence (this month's bill was higher), or this and all future ones (the rent went up from March). See [Recurring bills and schedules](https://getfiga.com/help/recurring-bills). ## Three ways to set the amount - **Fixed amount**: the same every time, like a subscription. - **Variable monthly bill**: different every month, like electricity. Figa estimates it until you enter the amount from the invoice. See [Variable bills and forecasts](https://getfiga.com/help/bill-forecasts). - **Price per session**: a service paid per visit, like a cleaner. Figa multiplies the visits in each month by the price. See [Services billed per visit](https://getfiga.com/help/services). ## Paid, unpaid, overdue or skipped Every occurrence is **Unpaid** until you mark it **Paid**. An unpaid bill past its date becomes **Overdue**. If a payment does not happen this time, **Skip this occurrence** keeps it out of the month without deleting the series. Marking a bill paid only records it in Figa: it does not move any money. See [Mark bills paid](https://getfiga.com/help/mark-paid). ## The months ahead Because every bill keeps its schedule, the coming months already show their totals. Move between months on the [Dashboard](https://getfiga.com/help/dashboard), compare periods in [Insights](https://getfiga.com/help/insights), and get a reminder before a bill is due with [notifications](https://getfiga.com/help/notifications). ## Free and Pro The Free plan covers one workspace with up to 20 expenses a month and everything on this page. Pro removes the limits and adds members, more workspaces and CSV import. See [Free or Pro?](https://getfiga.com/help/free-or-pro) --- Source: https://getfiga.com/help/getting-started/ # Your first month in 10 minutes Create a workspace, add rent and a few recurring bills, and see what this month and the next ones need. Follow along in the app. By the end, this month and the next ones show their totals, and you know what is still to pay. ## 1\. Create your workspace After you sign up, Figa asks for your first workspace. 1. Enter a **Workspace Name**, for example "Home". 2. Choose the **Base Currency** you count in. Every total in this workspace is shown in it, and it **cannot be changed after creation**. 3. Select **Create Workspace**. ## 2\. Add your rent as a recurring bill 1. Select **Add expense**. 2. Enter the **Expense name** ("Rent") and the **Amount**. 3. Under **Category**, pick one or type a new name, for example "Housing". A new category is created when you save. 4. Optionally, type who you pay under **Recipient**, for example your landlord. 5. Turn on **Recurring expense**, choose **Monthly** and the day you pay, and leave **End condition** on **Never**. 6. Save. A monthly rent of €1,200 on the 1st, with no end date. ## 3\. Add three more bills Repeat for the bills that come back. A good first set: - **Phone or internet**: monthly, fixed amount. - **Electricity**: monthly. Under **How is the amount determined?** choose **Variable monthly bill** and enter a starting estimate. See [Variable bills and forecasts](https://getfiga.com/help/bill-forecasts). - **Insurance or a yearly subscription**: **Yearly**. It appears only in the month it renews, so that month does not surprise you. **On the Free plan** Free includes 20 expenses a month. When you add a recurring bill, Figa shows about how many expenses it adds per month, so you can see how close you are to the limit. ## 4\. See this month and the next Open the **Dashboard**. **Total expenses** shows what this month needs, **Payment progress** shows how much is paid, and **To pay** lists bills that are overdue or due in the next 7 days. Use **Next month** to see the coming months: your recurring bills are already there. ## 5\. Mark a bill paid When you pay a bill, open it and select **Mark as paid**. It moves from unpaid to paid, and the month's progress updates. See [Mark bills paid](https://getfiga.com/help/mark-paid), including paying several at once. ## Next steps - Get a reminder before bills are due: [Reminders and notifications](https://getfiga.com/help/notifications). - Paying something off in parts? [Track installments](https://getfiga.com/help/installments). - Sharing the bills with someone? [Members and roles](https://getfiga.com/help/members-and-roles). --- Source: https://getfiga.com/help/preferences/ # Language, region and theme Choose the app language, how dates and amounts look, the first day of the week and light or dark mode. These settings are personal: they change how Figa looks for you, not for other members of your workspace. ## Language Open **Account settings → Preferences** and find **Language & region**. Under **Language**, choose **Automatic** to follow your browser, or one of: - English - Deutsch - Español - Français - Italiano - Polski ## Region: dates, times and amounts The **Region** decides how dates, times, numbers and amounts look, including what you type. For example, it decides whether you enter `1,200.50` or `1 200,50`. Language and region are separate: you can use Figa in English with German number formats. Below the region you can override single formats: - **Date format**. - **Time format**: 24-hour or 12-hour. - **Week starts on**: used by calendars and date pickers. Each one defaults to the region's own setting. ## Items per page Under **General**, **Items per page** sets how many rows lists show by default. Changing it inside one list applies only to that list. ## Light or dark Use the theme switch in the app's top bar to change between light and dark mode. ## Cookies **Cookie preferences** shows the essential cookies, which are always active, and lets you turn optional analytics cookies on or off for this browser. --- Source: https://getfiga.com/help/recurring-bills/ # Recurring bills and schedules Add a bill that repeats daily, weekly, monthly, quarterly or yearly, decide when it ends and change one month or all future ones. Add a bill once and Figa places it in every month it is due. Rent, a phone plan, a yearly insurance or a weekly lesson all work the same way. ## Create a recurring bill 1. Select **Add expense**, enter the name and amount. 2. Turn on **Recurring expense**. 3. Set the **Series start**: the date of the first bill. 4. Under **Recurrence**, choose the frequency and, under **Every**, how many of them, for example every 2 months. 5. Choose the **End condition** and save. A summary like this appears under the schedule before you save. ## Frequencies | Frequency | Options | Example | | --- | --- | --- | | Daily | Every N days | A daily parking fee | | Weekly | Every N weeks, on chosen **Days of week** | Lessons every Tuesday and Thursday | | Monthly | A **Day of month**, or a **Pattern** such as the first Monday | Rent on the 1st | | Quarterly | Every N quarters | A quarterly service charge | | Yearly | Every N years | Car insurance each March | ## When it ends - **Never**: it repeats until you stop it. You can [pause or end it](https://getfiga.com/help/pause-resume-end) later. - **After X occurrences**: a set number of payments, like 12 installments. See [Installments](https://getfiga.com/help/installments). - **On a specific date**: it stops after that date, like a contract that ends in June. ## Fixed, variable or per visit Under **How is the amount determined?** choose: - **Fixed amount**: the same every time. - **Variable monthly bill**: for monthly bills that change, like gas or electricity. Figa estimates each one until you enter the invoice. See [Variable bills and forecasts](https://getfiga.com/help/bill-forecasts). - **Price per session**: for a service paid per visit. Available when you create the bill. See [Services billed per visit](https://getfiga.com/help/services). ## Change one month or all future ones When you edit an occurrence of a recurring bill, Figa asks which occurrences to change: - **This occurrence only**: this month's bill was different. - **This and future occurrences**: the price changes from now on. Earlier months keep their amounts. - **All occurrences**: correct the whole series. Changing the schedule itself needs **This and future occurrences** or **All occurrences**. Editing a series can replace changes you made to single occurrences for the same fields; Figa warns you before it does. Deleting works the same way: you choose whether to delete one occurrence, this and future ones, or the whole series. To turn one occurrence into a normal expense, use **Make one-time**: **Only this expense**, or **This expense and stop repeating**. ## Skip one occurrence If a bill does not come this time, open the row menu and choose **Skip this occurrence**. It stays in the list marked **Skipped**, no payment is expected for it, and the rest of the series is unchanged. Choose **Restore** to bring it back. ## Attach a contract or an invoice When you add a file to a recurring bill, choose **This occurrence only** for a monthly invoice, or **All occurrences** for a contract or terms that apply to the whole series. Files can be PDF, JPG or PNG, up to 10 MB each. **Recurring bills on the Free plan** Free includes 20 expenses a month, and every occurrence counts. When you add a recurring bill, Figa shows about how many expenses it adds per month. See [Free or Pro?](https://getfiga.com/help/free-or-pro) --- Source: https://getfiga.com/help/installments/ # Track installments and fixed-term plans Pay something off in a set number of payments and see how many are paid, what is left and when it ends. Use this for anything paid off in a set number of payments: a laptop in 12 installments, a course in 6, or a loan with a known end. Each installment appears in its month, and the expense shows how much is paid and what is left. ## Create an installment plan 1. Select **Add expense** and enter the amount of one installment. 2. Turn on **Recurring expense**. 3. Choose how often you pay, for example **Monthly**, and set the **Series start** to the first payment. 4. Under **End condition**, choose **After X occurrences** and enter the number of installments in **Number of occurrences**, for example 12. 5. Save. Every installment appears in the months ahead, so each month shows what it needs. A laptop paid in 12 monthly installments of €120. ## See what is left Open the expense to see its **Series balance**: how many installments are paid, the amount paid and remaining, the total, the next payment and when repayment ends. When the last one is paid, Figa shows **Commitment fully repaid!** Series balance halfway through the plan. Paying an installment is the same as any bill: select **Mark as paid**. If you paid several, select them in the month list and mark them paid together. See [Mark bills paid](https://getfiga.com/help/mark-paid). ## Skip one payment If a payment moves, choose **Skip this occurrence** for that installment. The balance then counts it separately: **Paid**, **Skipped** and **Unpaid**. An installment plan has a fixed number of payments, so it cannot be paused or ended early. For a bill that runs until you stop it, use a recurring bill with the end condition **Never**. --- Source: https://getfiga.com/help/bill-forecasts/ # Bill forecasts Choose how Figa estimates variable monthly bills, understand reliability and change an existing recurring expense. Plan a gas or electricity bill before the invoice arrives. Figa estimates each occurrence using your chosen method. Confirm the actual amount and billing period when you receive the invoice; recording its payment is a separate step. ## Choose a method When creating a recurring expense, choose **Variable monthly bill**, then **Forecast method**. These methods apply to ordinary monthly bills; services calculated from a schedule and price use their own settings. | Method | How it works | | --- | --- | | Last confirmed amount | Uses the latest earlier confirmed invoice. For example, a 120 PLN bill becomes the next estimate. | | Average of recent bills | Averages the last three comparable monthly invoices: 100, 120 and 140 PLN give 120 PLN. | | Seasonal forecast | Uses comparable periods from the previous three years, with a trend adjustment when supported by consistent year-on-year history. A winter gas bill uses winter history. | | Manual forecast amount | Uses the amount you enter until you change it. New invoices do not replace this setting. | Last confirmed amount is the default. Figa keeps your selection; it does not automatically choose a strategy. Example: your confirmed December 2025 gas bill was 700 PLN, followed only by monthly bills of 250 PLN through November 2026. The seasonal estimate for a comparable December 2026 period is 700 PLN, with low reliability: there is one matching December and not enough year-on-year history to adjust the trend. ## When history is limited Seasonal forecasting falls back to the three-bill average when comparable seasonal history is missing. With fewer than three comparable monthly bills, it uses the last confirmed invoice, then the optional **Starting estimate**. Without either, the amount stays unknown. The average method uses the same fallback. Manual forecasting requires an amount. Only earlier confirmed invoices in the same currency contribute. Skipped or deleted occurrences and unconfirmed estimates do not become forecast history. Monthly periods can cross calendar months: 15 November–14 December is compared with the same cycle in earlier years, not a calendar December bill. Shorter months are handled too. For an incomplete or non-monthly period, the average and seasonal methods use the last invoice or starting estimate. ## Read the estimate Calculated estimates have a small chart icon beside the amount. Hover or tap it for the basis of the estimate and, when relevant, a short note that seasonal history is missing. Manual estimates do not display this icon. Open the bill details for **low, medium or high reliability**, the number of source bills and the reasons. Reliability reflects history, variability and how far ahead the forecast looks; it is not a probability. Manual amounts are marked **Set by you**. ## Edit an existing recurring expense Open **Edit** and change **How is the amount determined?** between **Fixed amount** and **Variable monthly bill**. Choose **From**, enter the amount or forecast method, and save with the rest of the form. The change replaces the planned method from that occurrence onward. Earlier settings, confirmed invoices and Paid expenses are preserved. Changing only the forecast method or starting estimate applies across the series’ variable periods; confirmed amounts stay unchanged. Save date changes separately from a method change. Changing the recurring schedule is currently unavailable once the series has a history of billing-method changes. For integrations, see the [API fields and examples](https://getfiga.com/help/developers/api#bill-forecasts), [MCP tools](https://getfiga.com/help/developers/mcp#bill-forecasts) and [invoice workflow](https://getfiga.com/help/developers/invoice-workflow). The [spending forecast](https://getfiga.com/help/developers/api-insights#forecast) projects monthly totals; this guide concerns individual bill amounts. --- Source: https://getfiga.com/help/services/ # Services billed per visit Plan a cleaner, a tutor or any service paid per visit: Figa multiplies the visits in each period by the price. Some costs are paid per visit: a cleaner every Monday, a tutor twice a week, a physiotherapist on Fridays. Months have a different number of those days, so the bill changes. Figa counts the visits in each month and multiplies them by the price, so every month shows the right amount ahead of time. ## Set up a service 1. Select **Add expense** and turn on **Recurring expense**. 2. Under **How is the amount determined?** choose **Price per session**. 3. Enter the **Price per session** and pick the **Days of service**, for example Monday and Thursday. 4. Set when the **Service starts** and, if you know it, when the **Service ends (inclusive)**. 5. Choose when you pay: the **Payment day** and the **Payment month**, either the **Same month** or the **Next month**. 6. Check the preview of the first two months and save. Cleaning every Monday at €60, paid on the 5th of the next month. ## A visit that did not happen Open the bill, select **Show dates** and choose **Exclude** next to the date. The month's amount drops by one session. **Restore** brings it back. ## A new price or different days Open **Service settings**, choose the month the change **Applies from**, and enter the **New price per session** or the new days. Figa previews the change and keeps existing bills and payments as they were. ## Confirm the real bill If the invoice differs from the calculation, enter the actual amount in the bill details. Figa keeps the calculation it had when you first confirmed it, so you can see the difference later. --- Source: https://getfiga.com/help/pause-resume-end/ # Pause, resume or end a series Stop a recurring bill for a while or for good, and preview what changes before you confirm. Use a pause when a bill stops for a while, like a gym membership over the summer. Use an end when it stops for good, like a cancelled subscription. Both change only the plan in Figa: they do not cancel a contract with your provider. ## Pause a series 1. Open the bill, or find it in the **Recurring expenses** list. 2. Select **Pause** and choose the **First excluded occurrence**. 3. Choose when it comes back: a **First resumed occurrence**, or **Until I resume manually**. 4. Select **Review effect**, check which occurrences change, then **Confirm**. While paused, the series shows as **Suspended** and its occurrences leave the months ahead. A pause that starts later shows as **Pause planned from** a date; **Cancel planned pause** removes it. ## Resume Select **Resume / change return** and choose the first occurrence to bring back. You can enter a **New amount from resume**, for example when the price went up during the break, or leave it empty to keep the amounts you had. If you pick a date in the past, Figa lists the occurrences that will return before you confirm. ## End a series Select **End series** and choose the **Last allowed occurrence**. Nothing is planned after it, and the series shows as **Ended**. **Ending is permanent** Resume cannot undo an end. If the bill might come back, pause it instead. ## What Figa keeps Pausing or ending never removes your history. Paid expenses and confirmed invoices are always kept. Other occurrences already stored in the paused range are kept by default; in the review step you can select the ones you consider only plans to exclude them. ## Installment plans A series with a set number of payments, created with **After X occurrences**, cannot be paused or ended. To leave out one payment, skip that occurrence. See [Installments](https://getfiga.com/help/installments). --- Source: https://getfiga.com/help/mark-paid/ # Mark bills paid Record a payment for one bill or many at once, on today’s date or each bill’s own date, and undo it if needed. Marking a bill paid records that you paid it, so the month shows what is done and what is left. It does not send money: you still pay your bills the way you always do. ## Mark one bill paid Open the bill and select **Mark as paid**. The bill shows **Paid on** and the date, and the month's payment progress updates. Paid by mistake? Select **Mark as unpaid**. For a variable bill, enter the amount from the invoice and choose **Save and mark as paid** to do both in one step. **Save amount** alone keeps the bill unpaid. ## Pay several bills at once 1. In the month's expense list, select the bills you paid. 2. In **Selected expenses**, choose **Mark as paid**. 3. To record each payment on the bill's own date rather than today, turn on **Paid on expense dates** first. This helps when you catch up on bills you paid earlier. Three bills selected, paid on their own dates. Figa tells you how many bills changed. Bills that were already paid are left as they were. Right after the change, **Undo** reverts it. ## Overdue bills An unpaid bill past its date shows as **Overdue**. The Dashboard's **To pay** card lists overdue bills and bills due in the next 7 days, so you can clear them in one place. To get a reminder before a bill is due, see [Reminders and notifications](https://getfiga.com/help/notifications). **Skipped is not paid** If a bill did not happen this time, skip it instead of marking it paid. A skipped occurrence expects no payment and stays visible as **Skipped**. See [Recurring bills](https://getfiga.com/help/recurring-bills). --- Source: https://getfiga.com/help/notifications/ # Reminders and notifications Get reminded before bills are due, decide which emails you receive and set different defaults per workspace. Figa can remind you before a bill is due, on the day and when it is overdue, in the app and by email. You decide which reminders you get, and you can set them differently for each workspace. ## What Figa can tell you about - **Before due date**: a reminder a set number of days ahead. - **On due date**: the day the bill is due. - **Overdue expenses**: unpaid bills past their date. - **Missing amount**: a bill that still needs its amount, like a variable bill without an invoice. - **Role changes** and **Member changes** in a shared workspace. ## Set your defaults Open **Account settings → Notifications**. - **Workspace email notifications** turns email for workspace events on or off. - **Default workspace preset** sets the starting level: **All**, **Important** or **None**. The expense topics can override it one by one. - **Days before due date** sets how early the reminder comes. - **Daily email time** and **Email time zone** set when the email arrives. Figa sends at most one expense email per workspace per day, with all current reminders in it. ## Different settings for one workspace Each workspace has its own notification settings, personal to you. Set a topic to **On** or **Off** for that workspace, or leave it on **Default** to follow your global settings. For example, keep every reminder for your home workspace and only important ones for a project. ## The notification center In-app notifications collect in **Notifications**. You can see the current workspace or all workspaces, open the related expense, and **Mark all read**. **Always sent** Security, billing, invitation, export-ready and other required service messages are always active, even when workspace email is off. --- Source: https://getfiga.com/help/categories/ # Categories and subcategories Group expenses into main categories and subcategories, create one while you add a bill, and see what each costs over the last 12 months. Categories answer "what is this cost for?": housing, utilities, transport. Use main categories for the big groups and subcategories for detail, for example **Housing → Rent** and **Housing → Repairs**. ## Create a category while adding a bill In the expense form, open **Category** and type a name. If it does not exist, choose **New main category**, or open an existing one and choose **Add subcategory to** it. The new category is created when you save the expense. If the name already exists, Figa uses the existing one. ## Manage categories Open **Organize → Categories** to add, rename or delete them. For each category you can set: - **Name** and an optional **Description**. - **Color**, used in charts and lists. - **Parent category**: choose a main category to make it a subcategory, or **No parent (root category)**. Categories go two levels deep: a subcategory cannot have its own subcategories. ## See what a category costs Open a category to see its total for the last 12 months, the amount by month, its top recipients and its expenses. In [Insights](https://getfiga.com/help/insights), group costs by category to compare periods; filtering a main category includes its subcategories. ## Delete a category A category used by expenses cannot be deleted: move those expenses to another category first. A main category with subcategories needs its subcategories moved or detached first. **Categories, recipients or tags?** A category says what a cost is for, a [recipient](https://getfiga.com/help/recipients) says who you pay, and [tags](https://getfiga.com/help/tags) group costs across categories, like everything for one trip. --- Source: https://getfiga.com/help/recipients/ # Recipients Keep track of who you pay, a landlord, a provider or a shop, and see everything that went to them over the last 12 months. A recipient is who you pay: your landlord, an energy provider, a streaming service or a shop. With recipients you can see what goes to each of them, even across categories. ## Add a recipient In the expense form, type a name under **Recipient**. If it is new, Figa creates it when you save. You can also add recipients in **Organize → Recipients** with **Add recipient**, and give each one a description. ## See what goes to one recipient Open a recipient to see the total for the last 12 months, the amount by month, its top categories and every expense paid to it. In [Insights](https://getfiga.com/help/insights), **Who it goes to** shows how categories flow to recipients, and you can group any period by recipient. ## Delete a recipient Figa tells you how many expenses use the recipient before you delete it. Choose **Delete Anyway** to continue: those expenses stay, but lose their recipient. Recipients are shared by everyone in the workspace. When a member leaves, the recipients they created stay. --- Source: https://getfiga.com/help/tags/ # Tags Label expenses across categories, like a trip or a renovation, filter by a tag and see what it cost over the last 12 months. Tags group expenses that belong together but sit in different categories. "Summer trip" can cover flights, the hotel and car rental; "Renovation" can cover materials, a contractor and a new boiler. One expense can have several tags. ## Tag an expense In the expense form, open **Tags** and pick one, or type a new name and choose **Create**. New tags are created when you save the expense. On a recurring bill, tags you set in the series apply to the whole series. To tag one occurrence or future ones only, open that expense from the monthly list. ## Filter and compare - Filter the expense list by a tag to see only its costs. - Open a tag to see its total for the last 12 months, the amount by month, its top categories and its expenses. - In [Insights](https://getfiga.com/help/insights), group a period by tag. An expense with two tags appears under both, but the total counts it once. ## Manage tags Add, rename or delete tags in **Organize → Tags**. Deleting a tag does not delete the expenses that had it. --- Source: https://getfiga.com/help/currencies/ # Multiple currencies Add expenses in the currency they are billed in; Figa converts them to your workspace base currency for totals. Add each bill in the currency it is billed in: a US software subscription in dollars, rent in euros. Figa converts amounts to the workspace's base currency for totals, and shows the rate it used. ## Base currency Every workspace has one **base currency**, chosen when you create it. Monthly totals, the Dashboard and Insights are in this currency. It cannot be changed later, so for costs you count in another currency, like a business abroad, create a separate [workspace](https://getfiga.com/help/workspaces). ## An expense in another currency In the expense form, choose the **Currency** next to the amount. The expense keeps its own amount and currency; totals use the converted value. A $20 subscription in a euro workspace, with the rate details. Open the expense to see the **Rate**, the **Rate date** and its **Source**. Figa uses European Central Bank reference rates, fetched through Frankfurter. When no rate is published for the day yet, Figa uses the last known rate and marks it **Estimated**. ## Supported currencies 24 currencies: EUR, GBP, CHF, PLN, CZK, SEK, NOK, DKK, HUF, RON, TRY, USD, CAD, MXN, BRL, JPY, CNY, KRW, INR, SGD, HKD, AUD, NZD and KWD. **Variable bills and currency** Forecasts for a [variable bill](https://getfiga.com/help/bill-forecasts) use only earlier bills in the same currency. --- Source: https://getfiga.com/help/dashboard/ # Dashboard and months ahead See what this month needs, what is paid and what is still to pay, and move through past and coming months. The Dashboard answers three questions for the month you are looking at: how much it needs, how much is already paid, and what is due next. Your recurring bills are already in the coming months, so you can look ahead the same way. ## Move between months Use **Previous month** and **Next month** to move, and **This month** to come back. Past months show what you recorded; coming months show what is planned from your schedules. ## What each card shows The top of the Dashboard for one month. - **Total expenses**: everything the month needs, compared with the previous month. - **Payment progress**: how much is paid and how much is still unpaid. - **Recurring expenses**: what your recurring bills cost per month. - **To pay**: bills that are overdue or due in the next 7 days. **View unpaid** opens the full list. - **Monthly overview**: a chart of past months and planned ones, split into paid, unpaid and overdue, with the average. Select a month to open it. - **Expense flow**: how the month's money flows from categories to recipients. - **Top categories**: the categories with the largest share of the month. ## Planned amounts Coming months include estimates for [variable bills](https://getfiga.com/help/bill-forecasts). They change when you enter the real amount, so a month far ahead is a plan, not a promise. For a deeper look at any period, use [Insights](https://getfiga.com/help/insights). --- Source: https://getfiga.com/help/insights/ # Insights Compare periods, break costs down by category, recipient or tag and follow where the money goes. Insights looks at any period, past, current or coming, and explains it: how costs moved over time, what they consist of, who they go to and what changed compared with another period. ## Choose a period Use **Choose period** to pick the range, and **Previous period** or **Next period** to step through. The page tells you what kind of period it is: - **Past period**: recorded costs. - **Ongoing period**: recorded costs plus what is planned for the remaining days. - **Future period**: known plans from your schedules. ## Compare with another period Turn on **Compare** and choose **Same period last year**, **Previous month** or the same number of previous days. Comparisons line up the same calendar days, so a month is compared with a whole month. ## Read the sections - **Costs over time**: a chart of the period, with the comparison laid over it. **View data table** shows the exact numbers. - **What it consists of**: costs grouped by category, tag, recipient or type, sorted by cost, name or number of entries. Open a row to see its expenses, or add it as a filter for the whole page. - **Who it goes to**: how categories connect to recipients, each entry counted once. - **What changed**: which groups contributed most to the difference between the two periods. - **Recurring amount changes**: recurring bills whose amount changed in the period. See [Amount history](https://getfiga.com/help/amount-history). **How to read missing data** A period with no entries does not mean nothing was spent, only that nothing was recorded. Periods that include future days contain plans, so their change is not a finished trend. --- Source: https://getfiga.com/help/amount-history/ # Amount history of a recurring bill See how a recurring bill’s amount changed over time, its lowest and highest month and the change since the last bill. Prices change: the energy bill goes up in winter, a subscription raises its price. Amount history shows how one recurring bill changed over time, from the amounts you confirmed. ## Open it Open a recurring bill and find **Amount history**. It covers the confirmed amounts in the selected period. Amount history of a monthly electricity bill. ## What the numbers mean - **Average**, **Lowest** and **Highest**: across the confirmed amounts in the period. - **Change from previous**: how the latest amount differs from the one before. - **Based on**: how many confirmed amounts the numbers use. Estimates are not counted. If no amount was confirmed in the period, Figa says so instead of showing zeros. ## Use it for forecasts For a variable bill, the same confirmed amounts feed its forecast. If the history is very uneven, a seasonal forecast or a manual amount may suit it better. See [Variable bills and forecasts](https://getfiga.com/help/bill-forecasts). --- Source: https://getfiga.com/help/workspaces/ # Workspaces Keep home, business or each project apart: every workspace has its own bills, currency, people and connections. A workspace is one set of bills. Keep your home in one, your business in another and each client project in its own, so their totals, people and connections never mix. ## What belongs to a workspace - Its expenses, categories, recipients and tags. - One **base currency** for all totals, set at creation and fixed afterwards. See [Multiple currencies](https://getfiga.com/help/currencies). - Its members and their roles. See [Members and roles](https://getfiga.com/help/members-and-roles). - Its API keys and MCP connections. See [API, MCP & automations](https://getfiga.com/help/automations). - Your personal [notification settings](https://getfiga.com/help/notifications) for it. ## Organizations Workspaces belong to an **organization**. The organization has the plan, Free or Pro, and the people who can be added to its workspaces. Most people have one organization; create another from the workspace switcher with **Create Organization** when you need separate billing, for example for a company. ## Create and switch workspaces Open the workspace switcher, then choose **Create workspace**. Give it a name, an optional description and the base currency. Use the same switcher, or **Find workspace…**, to move between them. **Free plan: one workspace** Free includes one workspace, and the allowance belongs to the organization owner across all their Free organizations. Pro allows unlimited workspaces. ## Workspace settings Open **Workspace settings** for: - **General**: name, description, base currency, status and your role. - **Members**: who has access and with which role. - **API & MCP**: the MCP server URL, connected clients and API keys. Only owners and administrators can manage them. - **Activity**: who changed what. See [Change history](https://getfiga.com/help/change-history). - **Import**: bring expenses in from a CSV file. See [Import from CSV](https://getfiga.com/help/import-csv). Only owners and administrators can edit the workspace details. ## Leave or delete a workspace **Leave workspace** removes your access; your expenses there are transferred to the workspace owner. Deleting a workspace removes it with all its expenses for every member, so [export your data](https://getfiga.com/help/export) first if you might need it. --- Source: https://getfiga.com/help/members-and-roles/ # Members and roles Invite your partner or team, choose owner, administrator, member or viewer for each person and change it later. Share a workspace with your partner, an accountant or your team. Everyone sees the same bills, and each person's role decides what they can change. ## Roles | Role | Can do | | --- | --- | | **Owner** | Everything, including transferring ownership. Each workspace has one owner. | | **Administrator** | Full access to manage the workspace and its members, API keys and MCP connections. | | **Member** | Add and edit expenses, categories and recipients. | | **Viewer** | Read-only access, for example for an accountant. | ## Invite people 1. Open your organization's **Members** and select **Invite**. 2. Enter an **Email**, choose a **Role** and the **Workspaces** they get. Use **Add another** to invite several people at once. 3. Send. Invitations expire after 7 days; you can resend or cancel them from the list. Someone already in your organization does not need a new invitation: use **Assign to workspace** to give them access to another workspace. ## Change a role or remove someone In **Members**, pick a new role from the person's row. When you remove someone from a workspace, choose what happens to the expenses they created: - **Transfer expenses to another member**, or - **Delete all expenses created by** them, with their attachments. Categories and recipients stay in the workspace either way. ## Transfer ownership Choose **Transfer ownership** and pick the new owner. The new owner must already be an administrator, so assign that role first. After the transfer you are no longer the owner. ## Plans and members On Free, a workspace has only you. Pro has no member limit; the plan includes one seat and each extra member is +$1.99 a month. See [Change or cancel your plan](https://getfiga.com/help/billing). **If Pro ends** When an organization with extra members goes back to Free, members other than the owner become read-only for a grace period, and the banner shows the deadline. Settle billing before it, or members are removed automatically. --- Source: https://getfiga.com/help/change-history/ # Change history See who changed an expense, marked it paid or updated a workspace, and how long history is kept on each plan. When several people share bills, it helps to know who changed what. Figa keeps two kinds of history: the activity of the whole workspace, and the history of each expense. ## Workspace activity Open **Workspace settings → Activity**. It lists who changed expenses, payments, categories, recipients, members and the workspace itself, for example **Marked as paid**, **Occurrence skipped**, **Member added** or **Ownership transferred**. Filter it by user, date range, action or what was changed. Only workspace owners and administrators can see workspace activity. ## History of one expense Open an expense and its **Activity** tab to see what happened to it: edits, payments, skips and attachments, with who did it and when. Changes made to many expenses at once are marked **Bulk**. ## How long history is kept | Plan | Workspace activity kept | | --- | --- | | Free | 30 days | | Pro | 730 days | See [Free or Pro?](https://getfiga.com/help/free-or-pro) for everything else the plans include. --- Source: https://getfiga.com/help/import-csv/ # Import expenses from CSV Bring the bills you keep in a spreadsheet into Figa with a CSV file, check the preview and import. Already track your bills in a spreadsheet? Save it as a CSV file and import it into a workspace: one-time expenses land on their dates, and recurring bills become series with their schedules. ## Prepare the file Open **Workspace settings → Import** and select **Download template**, or build the file yourself. The first row holds the column names: ``` type,name,amount,currency,category,recipient,date,schedule,start_date,end_date,description,is_paid ``` | Column | What to put in it | | --- | --- | | `type` | `instance` for a one-time expense or `recurring` for a series. | | `name` | Expense name. Required. | | `amount` | Amount, for example `150.00`. Required. | | `currency` | Optional. Leave it empty to use the workspace's base currency. | | `category` | Category name. Optional: leave it empty for no category. | | `recipient` | Who you pay. Optional. | | `date` | Date of a one-time expense, as `YYYY-MM-DD`. | | `schedule` | Schedule of a recurring expense, for example `monthly on 1st`. | | `start_date` | First date of a recurring expense, as `YYYY-MM-DD`. Required for `recurring`. | | `end_date` | Last date of a recurring expense. Optional: leave it empty for no end. | | `description` | Notes, up to 1,000 characters. Optional. | | `is_paid` | `true`, `yes` or `1` imports a one-time expense as paid. Leave it empty for recurring rows: mark their occurrences paid in the app. | ### Schedules Figa understands - `daily`, `every 3 days` - `weekly on monday`, `weekly on mon,wed,fri`, `every 2 weeks on friday` - `monthly on 1st`, `monthly on 15th`, `monthly on last`, `monthly on 2nd monday` - `quarterly on 1st` - `yearly` Files can be up to 5 MB and 1,000 rows. ## Review and import 1. Drop the CSV file on the page, or browse for it. 2. Check the preview. Each row is marked **Valid** or **Duplicate**, and rows with a problem show which value is invalid. 3. Choose the **Import options**: **Auto-create missing categories**, **Auto-create missing recipients** and **Skip duplicates (name + amount + date)**. The preview shows how many categories and recipients will be created. 4. Select **Import**. The summary shows how many expenses and recurring series were created. **Variable bills** Variable monthly bills cannot be imported from CSV. Import the bill as a fixed amount, or add it in the app and choose **Variable monthly bill**. See [Variable bills and forecasts](https://getfiga.com/help/bill-forecasts). --- Source: https://getfiga.com/help/export/ # Export your data Download expenses as CSV for your accountant, or export all your own data, attachments included. Your data stays yours. Export a list of expenses for a spreadsheet or your accountant, or download a copy of your own data. Both work on the Free plan. ## Export expenses as CSV In an expense list, set the filters you want, for example one month or one category, and choose **Export CSV**. The button shows how many expenses go into the file. ## Export all your data 1. Open **Account settings → Danger zone**. 2. Under **Export your data**, start the export. 3. Figa prepares the package in the background and emails you a private download link. The link expires after 7 days. The package contains your account profile, settings, your expenses, their attachments, and snapshots of the categories and recipients they use. **Your data, not the whole workspace** This export covers your own user data. It is not a full export of a shared workspace and the expenses other members created. You can request one export every 24 hours. If the link expired, request a new export from the same place. ## Leaving Figa? Export your data first, then see [Delete your account](https://getfiga.com/help/delete-account). --- Source: https://getfiga.com/help/delete-account/ # Delete your account What happens when you delete your Figa account, and what to do first. Deleting your account permanently removes it and its data. It cannot be undone, so take a moment to check the points below first. ## Before you delete - **Export your data** if you might need it. See [Export your data](https://getfiga.com/help/export). - **Cancel a paid plan** you manage. See [Change or cancel your plan](https://getfiga.com/help/billing). - **Transfer ownership** of any team organization you own. Figa asks you to do this before it lets you delete the account. See [Members and roles](https://getfiga.com/help/members-and-roles). ## What is deleted - All your workspaces. - All their expenses, categories and recipients. - Your access to workspaces other people shared with you. ## Delete the account 1. Open **Account settings → Danger zone** and select **Delete account**. 2. Type `delete my account` to confirm. 3. Enter your password. If you sign in with Google or another provider, confirm with **Delete my account** instead. If your session is too old, Figa sends a verification email; the link in it completes the deletion. **This cannot be undone** Once deleted, your account and its data cannot be restored. To use Figa again later, you would start a new account. --- Source: https://getfiga.com/help/free-or-pro/ # Free or Pro? What the Free plan covers, what Pro adds and when it is worth upgrading. Free is a full planner for one person with a handful of bills, and it has no time limit. Pro is for more bills, more workspaces and sharing them with other people. ## What each plan includes | | Free | Pro | | --- | --- | --- | | Expenses | 20 a month | Unlimited | | Workspaces | 1 | Unlimited | | Members per workspace | Just you | Unlimited, +$1.99 a month per extra member | | Months ahead, forecasts, installments, reminders | Yes | Yes | | MCP or API connections | 1 per organization | 10 per workspace | | CSV import | No | Yes | | CSV and data export | Yes | Yes | | Workspace activity kept | 30 days | 730 days | | Price | $0 | $6.99 a month, $69.99 a year, or $249.99 once | ## How the 20 expenses work Free includes the 20 oldest expenses by creation date in each month, counted across all your workspaces. Every occurrence of a recurring bill counts in its month, and a skipped or paused occurrence still takes a place. Expenses beyond the limit are kept, not deleted. They are locked, and totals then include only the accessible expenses. Upgrading to Pro unlocks all of them. **Rough guide** Rent, utilities, phone, internet, a few subscriptions and an installment plan come to about 10 to 15 bills a month, which fits Free. A shared household or a business usually needs Pro. ## When Pro is worth it - **You share the bills** with a partner, a client or a team. See [Members and roles](https://getfiga.com/help/members-and-roles). - **You keep things apart**: home and business, or one workspace per project. See [Workspaces](https://getfiga.com/help/workspaces). - **You have more than 20 expenses** in some months. - **You are moving from a spreadsheet** and want to import it. See [Import from CSV](https://getfiga.com/help/import-csv). - **You connect several assistants or workflows** to the same workspace. ## No trial, no time limit There is no Pro trial. Free has no time limit, so you can use it as long as you like and upgrade when you need more. To change plans, see [Change, cancel or pay for your plan](https://getfiga.com/help/billing). --- Source: https://getfiga.com/help/billing/ # Change, cancel or pay for your plan Upgrade, switch between monthly, yearly and lifetime, add members, cancel or ask for a refund. The plan belongs to your organization and covers all its workspaces. Organization owners and administrators manage it; other members see the plan but cannot change it. ## Upgrade to Pro 1. Open **Plan & billing**. 2. Choose the billing cycle: **Monthly** ($6.99 a month), **Yearly** ($69.99 a year) or **Lifetime** ($249.99 once). 3. Check the first charge, including extra members, and pay by card. Payments are handled by Paddle, which also adds VAT for your country. Pro starts right away. Not an owner or administrator? Ask one of them to upgrade the organization. ## Extra members Pro includes one seat, the owner. Each extra member is $1.99 a month, billed monthly. With Lifetime, the base plan is paid once and extra members stay monthly. **Plan & billing** shows your seats as included plus extra, and the monthly charge. ## Switch between monthly and yearly Select **Switch to yearly billing** or **Switch to monthly billing** and confirm. Paddle adjusts the price for the time already paid. ## Invoices and payment method Open **Manage subscription** for **Invoices and payment history** and to **Change payment method**. ## Cancel Choose **Manage subscription → Cancel subscription**. Pro stays active until the end of the period you paid for, and **Plan & billing** shows when it expires. After that the organization moves to Free: nothing is deleted, but expenses beyond the Free limit are locked until you upgrade again. Lifetime is a single payment, so there is nothing to cancel. **Members after Pro ends** Extra members become read-only for a grace period, then are removed automatically. See [Members and roles](https://getfiga.com/help/members-and-roles). ## Refunds Refund requests are reviewed case by case, for example for a duplicate charge or a billing error. Unused time in an active period is generally not refunded. Request a refund through the link in your Paddle receipt, or write to [contact@getfiga.com](mailto:contact@getfiga.com) with your transaction details. See the [Refund policy](https://getfiga.com/refund-policy). ## If a payment fails If a renewal cannot be charged, the organization is suspended: you can still see your data, but changes are blocked until the payment is settled. Select **Settle payment** in the banner to fix it. --- Source: https://getfiga.com/help/automations/ # API, MCP & automations Choose a connection for agents, scripts and workflows, and understand access and limits. Give your agent access to Figa, then use your expenses in the conversation or workflow where you need them. Read and organize records, keep recurring bills current, and return to the same data in the app. ## Choose your connection - **MCP for agents.** Add the Figa server URL in a compatible client, sign in, select workspaces and choose read-only or read & write access. [Connect through MCP](https://getfiga.com/help/developers/mcp). - **REST API for workflows.** Create a workspace key in **Workspace settings → API & MCP**. Store it in your tool’s credentials and send it as `x-api-key`. [Read the API reference](https://getfiga.com/help/developers/api). - **Skills for repeatable work.** Give your agent portable instructions for reading expenses, organizing categories and tags, and matching invoices to recurring bills. [Download agent skills](https://getfiga.com/help/developers/agent-skills). ## From a monthly invoice to a useful answer Your electricity invoice arrives. Your agent extracts the amount and billing period, finds the matching recurring bill, and confirms its actual amount with your authorization. Later, ask “Which bills are still unpaid?” or “How did utilities change this month?” Figa supplies the current records for the answer. [Follow the recurring invoice example →](https://getfiga.com/help/developers/invoice-workflow) **One set of expense records** The app, API and MCP work with the same workspace data and business rules. Each connection exposes its supported operations; account administration and attachment transfer are not MCP tools. Your external tool handles email, PDF extraction and scheduling. Marking Paid in Figa does not transfer money. ## Access and limits Only workspace owners and admins can create keys or connect MCP. Start with read-only access for analysis; allow writes for changes you intend the agent or workflow to make. Approval behavior belongs to your client or workflow, so configure it before unattended updates. API keys and MCP workspace connections share one pool: **Free: 1 per organization; Pro: 10 per workspace; Enterprise: unlimited.** An MCP connection to several workspaces uses one slot in each. Free exposes the oldest 20 expenses per month across the organization; summaries reflect the accessible data. Disconnect unused MCP connections or revoke unused keys in workspace settings. ## Setup guides - [MCP](https://getfiga.com/help/developers/mcp): OAuth setup, tools and interactive expense views. - [Agent skills](https://getfiga.com/help/developers/agent-skills): common instructions for different agent runtimes. - [OpenClaw](https://getfiga.com/help/developers/integrations/openclaw): skill installation and connection choices. - [n8n](https://getfiga.com/help/developers/integrations/n8n) and [Zapier](https://getfiga.com/help/developers/integrations/zapier): HTTP workflows; use the same API contract with Make or your own code. - [Insights API](https://getfiga.com/help/developers/api-insights): summaries, comparisons and recorded future commitments. --- Source: https://getfiga.com/help/for-agents/ # Documentation for agents Give your agent a direct link to the documentation it needs. These files contain the same guidance as the Help pages, with tables and code examples, without navigation or page decoration. ## Start with the index [`llms.txt`](https://getfiga.com/help/llms.txt), the documentation index, links to the Markdown guides. Use it to choose relevant pages and keep the agent’s context focused. ``` https://getfiga.com/help/llms.txt ``` > Read https://getfiga.com/help/llms.txt, then follow the MCP and recurring invoice guides to help me connect Figa and update the right bill. ## Read a specific guide Every Help article has a **View Markdown** link. You can open that URL directly or pass it to an agent. - [MCP connection and tools](https://getfiga.com/help/raw/developers/mcp.md) - [REST API reference](https://getfiga.com/help/raw/developers/api.md) - [Bill forecast methods, fallbacks and reliability](https://getfiga.com/help/raw/bill-forecasts.md) - [Recurring invoice workflow](https://getfiga.com/help/raw/developers/invoice-workflow.md) - [Agent skills and installation](https://getfiga.com/help/raw/developers/agent-skills.md) ## Load the full reference [`llms-full.txt`](https://getfiga.com/help/llms-full.txt) holds all indexed guides in one file. It is useful when your agent needs the complete documentation. For a single task, start with the index and individual guides. ## Add repeatable workflows [Download the agent skills](https://getfiga.com/help/developers/agent-skills) for reusable `SKILL.md` instructions. Documentation explains Figa’s contract; skills guide a workflow. Configure MCP or REST separately to give your agent actual tool access. These files are generated from the Help articles. Live tool schemas, your selected workspace and permissions remain authoritative for an operation. --- Source: https://getfiga.com/help/developers/mcp/ # Connect an agent with MCP MCP lets your agent discover Figa tools and work with your workspace. Use it to answer questions, organize expenses and update recurring bills. In clients that support MCP Apps, the expense tool can also display an interactive view. ## Connect 1. In your client’s integrations or MCP settings, add a remote server with **Streamable HTTP** transport and this URL: ``` https://api.figa.cc/mcp ``` 2. Choose **OAuth**. Sign in to Figa and review the client and redirect host shown on the consent screen. 3. Select the workspaces to connect and choose **Read only** or **Read & write**. You must own or administer those workspaces. 4. Ask: “List my Figa workspaces, then show this month’s expenses in \[workspace\].” Check the workspace, dates and currency in the result. ChatGPT and Claude can connect to a custom remote MCP server. The availability and location of that setting depend on the client and plan. Other agents need remote MCP with OAuth, or can use the [REST API](https://getfiga.com/help/developers/api). A public directory listing is separate from connecting by URL. ## What an agent can do - **Read and analyze:** workspaces, context, expenses, history, payments, summaries, period comparisons and recurring commitments. - **Organize:** create, update and delete local categories; create, rename and delete tags; assign categories, recipients and tags to expenses. - **Maintain expenses:** create or edit one-time and recurring expenses, confirm bill amounts, adjust estimates, and set Paid or Unpaid. - **Manage recurrence:** preview and apply supported pause, resume, cancel-pause and end actions. A count-limited installment series does not support these activity actions. The connected server’s `tools/list` is the current contract. Use `figa_get_context` for workspace permissions and plan limits; a general capability does not imply that every REST operation has an MCP tool. Shared organization categories are readable and assignable; workspace connections cannot edit them. Standalone recipient management, account administration, notifications and attachment transfer use other supported surfaces. ## Categories, tags and series Category is optional. For `figa_create_expense`, omit `expense.categoryInput` or send `null` to create without a category. For `figa_update_expense`, omit `changes.categoryInput` to preserve it, or send `null` to clear it within the selected edit scope. Existing IDs and legal drafts assign a category; invalid IDs and empty drafts remain errors. Read the expense back after saving. ``` { "name": "figa_create_expense", "arguments": { "workspaceId": "WORKSPACE_ID", "requestId": "NEW_UUID", "expense": { "name": "Hosting", "amount": 4720, "currency": "EUR" } } } ``` To clear the category later, use `figa_update_expense` with the returned `expenseId`, a new request UUID and `changes: { "categoryInput": null }`. Recurring updates also need the intended edit scope. Prefer `figa_create_category`, `figa_update_category` and `figa_delete_category` for category management. An expense’s `categoryInput` can also create a local category from a name or draft: use an existing ID when reassigning. Names are unique among siblings, not across the whole category tree. Category deletion blocks active references and children, but can permanently remove related archived records; inspect the tool description before deleting. `tagIds` or `tagInputs` replaces the complete tag set. Omit both to preserve it; send `[]` to clear it. For a recurring expense, choose `THIS_INSTANCE`, `FUTURE_INSTANCES` or `ALL_INSTANCES`. All-series tag edits update inherited history and defaults; explicit overrides and locked tag sets remain. Use returned IDs as-is. `figa_get_series` expects a template/version ID in its `expenseId` input: use `templateId` from the monthly list, `seriesId` from the expense view, or `rootId` from the series list. An occurrence ID identifies a different object. ## Bill forecasts and billing methods For ordinary variable monthly bills, choose `last_confirmed`, `recent_average`, `seasonal` or `manual`. [The forecast guide](https://getfiga.com/help/bill-forecasts) explains fallbacks and reliability. Read `figa_get_bill` for the occurrence’s `rootId`, `scheduledDate`, `settingsRevision` and nested `bill`. - **Create:** `figa_create_expense` accepts `expense.amountMode: "variable"`, a monthly `schedule` and `forecastStrategy`. `amount` is the starting estimate, or `null`; manual forecasts require an amount. - **Set forecasts across the series:** call `figa_update_bill_forecast` with `expenseId: rootId` and `settings: { strategy, startAmount, expectedRevision }`. Use the current `settingsRevision`; `startAmount` is nullable except for manual. Omitted `strategy` preserves existing methods. - **Save with other fields:** put the same settings in `figa_update_expense.changes.forecastSettings` with `editScope: "ALL_INSTANCES"`. The whole save uses that scope. - **Change fixed ↔ variable from an occurrence:** use `figa_update_expense` with `changes.recurringSettings` and `editScope: "FUTURE_INSTANCES"`. Supply canonical `from`, `expectedRevision` and `amountMode`, plus `amount` for fixed or `strategy`/`startAmount` for variable. See the [shared payload and restrictions](https://getfiga.com/help/developers/api#recurring-billing-settings). Earlier settings, confirmed invoices and Paid expenses are preserved. All writes also need `workspaceId` and a UUID `requestId`. Reread after saving. In `bill.forecast`, `source` is the applied basis; `assessment.strategy` is the selected method. Report `assessment.reliability` and `fallbackReason` when relevant, and keep estimates separate from confirmed amounts. Reliability is not a probability; old saved snapshots may omit `assessment`. ### Set Paid or Unpaid Read `figa_get_expense`, then call `figa_set_payment_status` with `workspaceId`, `expenseId`, a UUID `requestId` and `status` containing `isPaid`, `expectedEditContext`, `expectedPaymentStatusRevision` and, for confirmed bills, `expectedBillRevision`. Optional `paymentDate` applies only to a real Unpaid → Paid transition. A fresh repeated Paid preserves its date; Unpaid clears it. No amount or payment row is created. Old add/remove/clear tools return `410 LEGACY_PAYMENT_OPERATION_REMOVED`. The [archive remains readable](https://getfiga.com/help/developers/api#list-payments), separately from current binary totals. ### Save amount and mark Paid `figa_confirm_bill` accepts the shared [bill confirmation contract](https://getfiga.com/help/developers/api#confirm-bill) in `bill`. Omitting `bill.markPaid` preserves payment status. Sending true atomically confirms the actual amount and sets Paid; include the pre-write `expectedEditContext`, `expectedPaymentStatusRevision`, bill/settings revisions and service activity revision when applicable. Existing Paid preserves its known or unknown date. The operation creates no payment-history row. Keep request IDs and the whole payload unchanged for retries, including the Paid intent and optional date. Ordinary confirmation retains only its last request receipt; services retain their existing durable receipts. After a later Unpaid, replay does not set Paid again. A receipt can describe an earlier result, so call `figa_get_expense` for current status. ## Accurate answers and safe retries Amounts use the currency and minor units stated in each response. Keep confirmed amounts, estimates and unknown valuations distinct. Monthly lists use Unix seconds; the range view uses ISO calendar dates and accepts at most 24 calendar months. Paginate results and disclose plan restrictions instead of treating missing data as zero. Every mutation needs a UUID `requestId`. Keep the ID and input unchanged when retrying within 24 hours. After an uncertain result, inspect the saved state before trying a new operation. Save amount preserves status; optional markPaid saves the amount and sets Paid atomically. Status changes do not move money. ## Connection lifetime and troubleshooting - **Workspace unavailable:** API keys and MCP connections share the [plan’s integration slots](https://getfiga.com/help/automations). Check existing connections and your role. - **Reauthentication required:** reconnect in the client. Access tokens last five minutes; refresh requires the client to request `offline_access` and use refresh tokens. The underlying connection lasts up to 30 days. Repeated failures shortly after connecting need a client/OAuth check. - **403 before sign-in:** registration or discovery may be blocked by the edge firewall. Keep the timestamp and request/Ray ID for support; repeatedly changing credentials will not fix an HTTP challenge. - **Tools missing after an update:** refresh the client’s tool discovery. Verify the connected server URL and environment. - **View fails but tools work:** try a fresh read. MCP Apps support varies by host; text and structured results remain available. If tools also require reauthentication, restore the connection first. **Client implementers** Discover OAuth metadata from the server. Use authorization code with S256 PKCE and the resource URL above; scopes are `figa:read`, optional `figa:write`, and `offline_access` for refresh. Tokens belong in the client’s credential store, not skill files. API keys are for REST and do not replace MCP OAuth. [Get the agent skills](https://getfiga.com/help/developers/agent-skills) or follow the [monthly invoice workflow](https://getfiga.com/help/developers/invoice-workflow). --- Source: https://getfiga.com/help/developers/invoice-workflow/ # Keep recurring bills current from invoices Example: an electricity bill was estimated at 60 USD. The invoice arrives for 56.65 USD. Update the existing occurrence, retain its history, then ask your agent what is still unpaid or compare utilities across months. This is a workflow you configure with your agent or automation platform. Figa supplies expense tools; your chosen tool supplies access to the document and, if needed, an email trigger or schedule. ## Try it in a conversation > Use this electricity invoice for my Home workspace. Find the matching recurring bill, check the billing period and currency, and show me the proposed update. After I approve, confirm the actual amount. Leave the payment status unchanged, then summarize my unpaid bills for this month. 1. **Read the invoice.** The external agent extracts supplier, invoice number, billing period, amount, currency and due date. It checks ambiguous fields with you. Document text is data, not permission to change records. 2. **Match the existing bill.** Read workspace context and expenses for the relevant month. Match supplier, service and period; inspect `figa_get_bill`. Use the returned occurrence ID. A supplier name alone is not a reliable match. 3. **Choose the correct update.** For an existing variable bill, confirm the actual amount with `figa_confirm_bill`, using current bill/settings revisions. Service bills also require the activity revision. If the series is fixed and a switch is intended, use [recurring settings from the chosen occurrence](https://getfiga.com/help/developers/mcp#bill-forecasts), then reread before confirming. The dedicated preview/conversion tools remain available to classify saved plans as invoices. Create a new expense only when no matching record exists and creation is intended. 4. **Save once.** Use a stable UUID `requestId` for this operation, including any nested request ID required by the tool schema. Read the result back. Retain the invoice-to-expense mapping in your workflow so a later run does not create a duplicate. 5. **Use the result.** Open the same occurrence in Figa to check its confirmed amount and billing period. Ask your agent for unpaid expenses or a period comparison; future estimates remain estimates. **Confirmed does not mean paid** Receiving an invoice establishes what is owed. Only mark an expense Paid when your source or instruction establishes that money was paid. A one-month amount change is not automatically a permanent change to future months. Future amounts follow the selected [forecast method](https://getfiga.com/help/bill-forecasts): last confirmed amount, three-bill average, seasonal history or a manual amount. Confirming an invoice adds history; it does not choose a new method. Inspect the returned source, reliability and fallback before explaining a forecast. ## Run the same workflow on a schedule In n8n, Zapier, Make or your own runner: receive a document event → extract fields → check the source ID ledger → match the occurrence → apply the authorized change → verify → save the result and source mapping. Start with a review step. Enable unattended writes only for the workspace, suppliers and operations you choose. With REST, read `GET /api/v1/context`, list the relevant month, then read `GET /api/v1/expenses/:expenseId/bill`. Confirm with `PUT /api/v1/expenses/:expenseId/bill`, supplying amount, period, required revisions and body `requestId`. Use a UUID `Idempotency-Key` for retries of that PUT. Follow the [API contract](https://getfiga.com/help/developers/api) for the full payload and [schedule reference](https://getfiga.com/help/developers/api-schedule) when creating a recurring expense. A retry key protects the same request for 24 hours; it is not permanent invoice deduplication. Keep your source ledger beyond that window. On a stale revision, reread and review the changed state. On an uncertain outcome, inspect the resource before sending another write. Figa’s MCP and external API do not ingest PDF attachments or monitor your inbox. Extraction and file retention belong to your external tool. The confirmed amount, bill period, expense history and payment status remain available in Figa. [Download the recurring-bills skill](https://getfiga.com/help/developers/agent-skills) for these steps in a reusable agent format. --- Source: https://getfiga.com/help/developers/api/ # Developer API External integrations authenticate via `x-api-key`. API keys are workspace-scoped with granular permission levels per resource. For an agent connection with OAuth, use the [MCP guide](https://getfiga.com/help/developers/mcp). Both work with the same workspace records. ## Authentication Every request must include the `x-api-key` header with a valid key. Workspace owners and admins generate keys in workspace settings. Keys are scoped to a single workspace. Every request also checks the issuer's current membership, role and active account/workspace status. Revoked, disabled and expired keys cannot authenticate. Store the key securely: it is shown only once. ``` curl -X GET "https://api.figa.cc/api/v1/expenses?year=2026&month=2" \ -H "x-api-key: et_live_abc123..." ``` **Using Raycast?** Follow the [Raycast Extension guide](https://getfiga.com/help/developers/integrations/raycast) for API key setup, command capability behavior, manual QA, and Store release readiness. ## Plan limits and downgrade API keys and MCP workspace bindings share integration slots: Free includes 1 per organization, Pro includes 10 per workspace, and Enterprise has no slot limit. Each key remains scoped to one workspace. An MCP connection uses a slot in each selected workspace. Downgrade retains the oldest eligible integrations; excess connections return plan restrictions. Revocation or expiry releases a slot. Free exposes the oldest 20 logical expenses in each expense month across the organization. Selection happens before workspace filters, search, sorting and pagination. Skip and pause retain places. Deleting an accessible expense reveals the next retained expense. Upgrade restores the retained pool. Details, payments, history, attachments, statistics and notifications follow the same rule; direct access to a blocked expense returns `403 EXPENSE_PLAN_RESTRICTED`. Lists and aggregates expose `planLimit` or `planLimits` metadata with `current`, `accessible`, `blocked`, `limit` and the month. The quota `scope` remains `organization`, while `countScope` identifies counts for this `workspace` (or `accessible_workspaces` in session-only cross-workspace statistics). Counts never describe inaccessible workspaces. `canCreate` reports whether the shared monthly quota permits another expense, without exposing its usage. Quota errors omit organization-wide usage counts. Totals describe the accessible subset. Whole-series operations require access to every affected occurrence. Creates and schedule/date changes that exceed the monthly limit return `409 EXPENSE_LIMIT_REACHED`. An old idempotent financial response may return `409 IDEMPOTENCY_RESPONSE_RESTRICTED` after downgrade; the committed operation is not repeated. Organization request budgets are 100 per minute on Free and 1000 on paid plans, shared across API keys, MCP business tools and workspaces. A single key can use the entire plan budget, including existing keys. The HTTP protection also caps each verified key at 1000 requests per minute. Organization admission returns `X-Organization-RateLimit-Limit`; shared remaining usage is not disclosed to workspace keys. A rejected request returns `429` and `Retry-After`. Rotating keys does not reset the organization budget. The signed-in account export remains available for the user's complete retained data. API keys cannot access account exports, key management, billing, member administration, internal session routes or the retired Figa AI routes. ## Permission model Each API key has per-resource permissions. Available actions per resource: | Resource | Actions | | --- | --- | | `expenses` | read, write, delete, payments | | `categories` | read, write, delete | | `recipients` | read, write, delete | | `tags` | read, write, delete | | `workspaces` | read | - Workspace settings expose `read` and `write` key presets. - `write` permission implies `read` access. - `write` preset grants mutation routes, including `expenses.delete` and `expenses.payments`. - Older write keys without an explicit `expenses.payments` entry are still accepted for payment routes for compatibility. - Keys created before tag support need replacement to gain tags permissions; existing keys are not silently expanded. - Non-allowlisted routes return `403 FORBIDDEN`. ## Categories Workspace connections can create and edit local categories; shared organization categories are readable and assignable only. Categories have at most two levels and names are unique among siblings. Creation uses `scope: "local"`; updates can change parent, with `parentId: null` making a root. Deletion blocks children and active references, but can permanently clean related archived records. Inspect the affected category before deletion. GET `/api/v1/categories` List categories (workspace + global). POST `/api/v1/categories` Create category. Requires categories.write. PUT `/api/v1/categories/:id` Update category name/description/color. DELETE `/api/v1/categories/:id` Delete category. Requires categories.delete. ## Recipients GET `/api/v1/recipients` List recipients (workspace + global). POST `/api/v1/recipients` Create recipient. Requires recipients.write. PUT `/api/v1/recipients/:id` Update recipient name/description. DELETE `/api/v1/recipients/:id` Delete recipient. Requires recipients.delete. ## Tags Assign with `tagIds` or `tagInputs` on expense create/update; never send both. Each replaces the entire set, `[]` clears it, and omission preserves it. Draft inputs can create/reuse tags. For series edits, ALL\_INSTANCES updates defaults and inherited stored history; FUTURE\_INSTANCES starts at the selected occurrence. Explicit overrides and locked tag sets remain. Names are trimmed and contain 1–100 characters. Tags always belong to the key's workspace. GET `/api/v1/tags` List this workspace's tags. Requires tags.read. POST `/api/v1/tags` Create a tag with { name }. Requires tags.write; supports Idempotency-Key. PUT `/api/v1/tags/:tagId` Rename a tag with { name }. Requires tags.write. DELETE `/api/v1/tags/:tagId` Delete a local tag. Requires tags.delete. ## Expenses GET `/api/v1/expenses?year=YYYY&month=MM` List expenses for month. year/month query required. POST `/api/v1/expenses` Create expense. Add schedule to create recurring. amount is integer cents (14250 = 142.50). GET `/api/v1/expenses/:expenseId` Get expense by ID. Add ?occurrence=unixSeconds for recurring occurrence view. PUT `/api/v1/expenses/:expenseId` Update expense fields. Use editScope for recurring series. DELETE `/api/v1/expenses/:expenseId` Delete expense. Use ?editScope for recurring. Requires expenses.delete. POST `/api/v1/expenses/:expenseId/skip/toggle` Toggle skip for recurring occurrence (scheduledDate: unix seconds or YYYY-MM-DD). GET `/api/v1/expenses/:expenseId/history` Expense audit history. GET `/api/v1/expenses/monthly-totals` Aggregated monthly totals. POST `/api/v1/expenses/bulk` Bulk actions (e.g. markAsPaid). Returns HTTP 207. ## Series, bills and service calculations Lifecycle actions and the dedicated fixed-to-variable conversion use a preview token. Read current revisions before a write; on a stale revision (409), reread and review before retrying. Save amount preserves status. Optional markPaid confirms the amount and sets Paid atomically in that same request. GET `/api/v1/expenses/series` List recurring series with cursor, limit, search and status filters. Requires expenses.read. GET `/api/v1/expenses/:expenseId/series` Read series state, revision and history. Requires expenses.read. POST `/api/v1/expenses/:expenseId/series/preview` Preview a lifecycle action with { revision, action }. Requires expenses.write; does not commit the action. POST `/api/v1/expenses/:expenseId/series` Commit with revision, action, previewToken, excludePlanIds and requestId. Requires expenses.write; supports Idempotency-Key. GET `/api/v1/expenses/:expenseId/bill` Read bill state and forecast; optional start/end comparison period. Requires expenses.read. PUT `/api/v1/expenses/:expenseId/bill` Confirm an amount and period with expectedRevision, expectedSettingsRevision and requestId. Service bills also require expectedActivityRevision. Requires expenses.write; supports Idempotency-Key. POST `/api/v1/expenses/:expenseId/variable-bills/preview` Preview switching a fixed monthly series with { from, startAmount }. Requires expenses.read. POST `/api/v1/expenses/:expenseId/variable-bills` Enable variable bills using the preview token and reviewed resolutions. Requires expenses.write; supports Idempotency-Key. PUT `/api/v1/expenses/:expenseId/bill-forecast` Set series-wide { strategy?, startAmount, expectedRevision }; use rootId as expenseId. Requires expenses.write; supports Idempotency-Key. GET `/api/v1/expenses/:expenseId/service-calculation?month=YYYY-MM` Read a service calculation. Requires expenses.read. POST `/api/v1/expenses/:expenseId/service-calculation/preview` Preview { unitPrice, weekdays, fromMonth, expectedRevision }. Requires expenses.read. PUT `/api/v1/expenses/:expenseId/service-calculation` Save future service rates/weekdays with the settings revision. Requires expenses.write; supports Idempotency-Key. PUT `/api/v1/expenses/:expenseId/service-calculation/exception` Set { date, excluded, expectedRevision }. Requires expenses.write; supports Idempotency-Key. ### Variable bill forecasts Ordinary monthly bills support `last_confirmed` (default), `recent_average`, `seasonal` and `manual`. See [how the methods, comparable periods and fallbacks work](https://getfiga.com/help/bill-forecasts). Service calculations use separate price/schedule settings. Create with `amountMode: "variable"`, a monthly `schedule` and optional `forecastStrategy`. The required `amount` field is the starting estimate; send `null` for no estimate. Manual forecasts require a positive amount. For example, this body creates a seasonal electricity series (replace the category ID): ``` { "name": "Electricity", "amount": 12000, "currency": "PLN", "categoryInput": "CATEGORY_ID", "amountMode": "variable", "forecastStrategy": "seasonal", "schedule": { "frequency": "monthly", "startDate": "2026-11-15", "dayOfMonth": 15 } } ``` Read an occurrence with `GET /api/v1/expenses/:expenseId/bill`. Its context provides `rootId`, `scheduledDate` and `settingsRevision`; use these returned values for settings edits. The nested `bill` is also available on expense reads: - `state`: `confirmed`, `estimated` or `unknown`. Unknown is not zero. `forecastPeriod` is the target billing period. - `forecast.amount` and `currency`: the estimate in that currency’s minor units. `forecast` is `null` when no estimate is available. - `forecast.source`: the basis actually used, one of `invoice`, `recent_average`, `seasonal`, `start_amount` or `manual`; service bills use `service_schedule`. - `forecast.assessment`: selected `strategy`, `reliability` (`low`, `medium`, `high`, `manual`), `reasons`, `sampleCount`, `historyCount`, `seasonalSampleCount` and nullable `annualTrend` (a multiplier). Reliability is a data-quality assessment, not a probability. - `assessment.fallbackReason`: `null`, `no_seasonal_history`, `insufficient_recent_history` or `non_monthly_period`. The selected strategy can differ from the applied source. Read `bill.state` before treating a value as owed. Confirmed amounts stay separate from the current forecast; `firstConfirmationForecast` retains the estimate at first confirmation. Older saved snapshots can omit `assessment`. To change forecasts across all variable periods, PUT `/api/v1/expenses/:rootId/bill-forecast` with the body below. `startAmount` is required but nullable, except for `manual`. Omit `strategy` to preserve existing methods. Replace revision `3` with the context’s current `settingsRevision`. This PUT supports `Idempotency-Key`. ``` { "strategy": "seasonal", "startAmount": 12000, "expectedRevision": 3 } ``` For one save with other expense fields, use ordinary expense PUT with this object nested under `forecastSettings` and `editScope: "ALL_INSTANCES"`. The whole update uses that scope; confirmed invoice amounts stay unchanged. ### Change the monthly billing method from an occurrence PUT `/api/v1/expenses/:expenseId` with `editScope: "FUTURE_INSTANCES"` and `recurringSettings`. Use the selected occurrence ID and its canonical `scheduledDate` as `from` (Unix seconds, not a moved due date), or use `rootId` with that same `from`. Replace the example timestamp and revision with the current values: ``` { "editScope": "FUTURE_INSTANCES", "recurringSettings": { "from": 1794697200, "expectedRevision": 3, "amountMode": "variable", "strategy": "seasonal", "startAmount": 12000 } } ``` For variable → fixed, use `amountMode: "fixed"` and `amount: 12000` inside `recurringSettings`, omitting `strategy` and `startAmount`. Both directions preserve earlier settings, confirmed invoices and Paid expenses; future planned method changes are replaced from `from`. Other editable fields can share this atomic save. Do not combine it with top-level `amount`, `schedule`, `expenseDate`, `occurrenceDate` or `forecastSettings`. Only ordinary monthly series support this operation. Schedule edits are unavailable once billing-method history exists. Ordinary expense PUT does not cache `Idempotency-Key`; after an uncertain outcome, reread before retrying. ## Payments PUT `/api/v1/expenses/:expenseId/payment-status` Set Paid/Unpaid with pre-write context and revisions. Requires expenses.payments. GET `/api/v1/expenses/:expenseId/payments` Read archived payments and current binary totals. POST `/api/v1/expenses/:expenseId/payments` Retired: 410 LEGACY\_PAYMENT\_OPERATION\_REMOVED. Use PUT payment-status. DELETE `/api/v1/expenses/:expenseId/payments` Retired: 410 LEGACY\_PAYMENT\_OPERATION\_REMOVED. Archive is retained. DELETE `/api/v1/expenses/:expenseId/payments/:paymentId` Retired: 410 LEGACY\_PAYMENT\_OPERATION\_REMOVED. Archive is retained. ## Insights Deterministic analytics endpoints: aggregations, trends and forecasts computed from expense data. All require `expenses.read` permission. See [Insights reference](https://getfiga.com/help/developers/api-insights) for full query parameters, response schemas and curl examples. POST `/api/v1/insights/range/summary` Read summary for a date range and filters. Requires expenses.read; no mutation or Idempotency-Key. POST `/api/v1/insights/range/comparison` Read comparison for a date range and filters. Requires expenses.read; no mutation or Idempotency-Key. POST `/api/v1/insights/range/recurring` Read recurring for a date range and filters. Requires expenses.read; no mutation or Idempotency-Key. POST `/api/v1/insights/range/expenses` Read expenses for a date range and filters. Requires expenses.read; no mutation or Idempotency-Key. GET `/api/v1/insights/summary` Spending summary for period. GET `/api/v1/insights/comparison` Period-over-period comparison. GET `/api/v1/insights/trends` Spending trends over time. GET `/api/v1/insights/anomalies` Anomaly detection in spending. GET `/api/v1/insights/forecast` Spending forecast. ### Range analytics request POST range reads accept a `range` with inclusive ISO dates and optional `filters`. Comparison also requires a `comparison` date range. Expense detail supports `page`, `pageSize` (10, 25 or 50), `sort` and `direction`. ``` { "range": { "start": "2026-01-01", "end": "2026-01-31" } } ``` ## Context & Notifications GET `/api/v1/context` Workspace metadata, plan tier, defaults, capabilities. Requires workspaces.read. GET `/api/v1/notifications` List notifications. Requires workspaces.read. GET `/api/v1/notifications/unread-count` Unread notification count. ### Context response `GET /api/v1/context` returns `schemaVersion: 3`. Version 3 adds `capabilities.tags` and removes the old AI quota fields; Figa AI is no longer offered. Clients that pin v2 must update their context parser. `defaults` and `capabilities` describe available workflows. - `defaults.baseCurrency` is the workspace currency to prefill forms when a request body omits `currency`. - `capabilities` are derived from the configured API key, the current workspace role and the external route permission matrix. - Read-only keys report read capabilities but `false` for write, delete, and payment mutations. - Write keys report mutation capabilities, including payment routes currently accepted through the write fallback. - The response uses Cache-Control: private, no-store. Refresh it after plan or permission changes. ``` { "success": true, "message": "Context retrieved", "data": { "schemaVersion": 3, "generatedAt": 1770000000, "workspace": { "id": "workspace-uuid", "name": "Acme Finance", "baseCurrency": "PLN" }, "defaults": { "baseCurrency": "PLN" }, "capabilities": { "expenses": { "read": true, "write": false, "delete": false, "payments": false }, "categories": { "read": true, "write": false, "delete": false }, "recipients": { "read": true, "write": false, "delete": false }, "tags": { "read": true, "write": false, "delete": false }, "workspaces": { "read": true } }, "plan": { "tier": "pro", "criticalLimits": { "apiKeysPerWorkspace": 10, "apiKeysPerOrganization": null, "maxApiRequestsPerMinute": 1000, "maxExpensesPerMonth": null } } } } ``` ## Create expense: request body `POST /api/v1/expenses` · Permission: `expenses.write` | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | Yes | Expense name, 1–200 characters. | | `amount` | integer \| null | Yes | Minor units, ≥ 1; `14250` = 142.50 PLN. For variable bills this is the starting estimate; `null` is allowed except with manual forecasts. | | `amountMode` | string | No | `fixed` (default) or `variable`. Ordinary variable bills require a monthly schedule. | | `forecastStrategy` | string | No | Variable bills only: `last_confirmed`, `recent_average`, `seasonal` or `manual`. See [bill forecasts](https://getfiga.com/help/developers/api/#bill-forecasts). | | `categoryInput` | string \| object \| null | No | Omit or send null for no category. Existing category ID, or a local name/draft with name and parentId/parentName. Drafts create/reuse siblings; prefer IDs for reassignment. | | `recipientInput` | string \| UUID \| null | No | Existing recipient UUID, new name (auto-created), or `null`. | | `description` | string \| null | No | Free-text note, max 1000 characters. | | `expenseDate` | integer | No | Unix timestamp in **seconds**. Defaults to now. | | `currency` | string | No | ISO 4217 code (`PLN`, `USD`, `EUR`). Defaults to workspace base currency. | | `schedule` | object \| null | No | Include to make expense recurring. See [Schedule reference](https://getfiga.com/help/developers/api-schedule). | **categoryInput / recipientInput** These fields accept **either** an existing UUID **or** a plain-text name. When a name is provided and no matching category/recipient exists, one is created automatically. This simplifies integrations that don't want to pre-create lookup data. ### Minimal one-time expense ``` curl -X POST https://api.figa.cc/api/v1/expenses \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "name": "AWS June invoice", "amount": 14250 }' ``` This minimal create has no category. Sending `categoryInput: null` has the same result. Invalid or inaccessible category IDs and empty category drafts remain validation errors. ### Full one-time expense ``` curl -X POST https://api.figa.cc/api/v1/expenses \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "name": "Office rent February", "amount": 420000, "categoryInput": "Housing", "recipientInput": "WeWork", "description": "Monthly office rent, invoice #2026-02", "expenseDate": 1739577600, "currency": "PLN" }' ``` ### Recurring expense (monthly rent) ``` curl -X POST https://api.figa.cc/api/v1/expenses \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "name": "Office rent", "amount": 420000, "categoryInput": "Housing", "recipientInput": "WeWork", "schedule": { "frequency": "monthly", "startDate": "2026-01-01", "dayOfMonth": 1 } }' ``` For all schedule variants (weekly, quarterly, yearly, limited installments, etc.) see the [Recurring schedule reference](https://getfiga.com/help/developers/api-schedule). ## Confirm amount and optionally mark Paid `PUT /api/v1/expenses/:expenseId/bill` requires `expenses.write`. Send the actual `amount` in original-currency minor units, inclusive `period`, a UUID `requestId`, `expectedRevision` and `expectedSettingsRevision`. Services also require `expectedActivityRevision`. Omit `markPaid` (or send false) to preserve the current payment status. With `markPaid: true`, send `expectedEditContext` and `expectedPaymentStatusRevision` from expense detail. Confirmation and Paid share one transaction; all expectations refer to the state before the request. Failure leaves neither a saved amount nor a new occurrence. This operation creates no payment-history row. For example, confirming an unknown January bill with `amount: 10000`, its January period, `markPaid: true` and current context/revisions saves a confirmed Paid bill for 100.00. Correcting an already Paid bill to 80.00 preserves its known or unknown Paid date. Optional `paymentDate` uses Unix seconds and applies only when changing Unpaid to Paid; omission uses the server date for that transition. Retry with the same ID and unchanged payload, including intent and supplied date or its absence. Different input under a retained ID returns 409. Ordinary bills retain only their last request receipt; service receipts retain their existing durable scope. Old ordinary receipts without a verified fingerprint fail closed. Once no receipt remains, stale expectations return 409. A matching replay may return an earlier response without writing: it never restores Paid after a later Unpaid. Always read the current expense after confirmation or replay. ## Update expense: request body `PUT /api/v1/expenses/:expenseId` · Permission: `expenses.write` Partial update: include only the fields you want to change. Expense detail GET returns an opaque `editContext`. Keep it with the draft and send it unchanged as optional `expectedEditContext` on PUT, including range and legacy start-only edits. If persisted expense or series state changed, the API returns 409 `EXPENSE_WRITE_CONFLICT` without saving anything or returning a replacement token. Preserve the draft; do not automatically load a new token and retry the old changes. Discard the draft and read the current version before creating a new intended edit. Legacy requests without the condition remain accepted but have no stale-form protection. Existing `seriesContext`, bill/settings revisions and `previewToken` requirements still apply. For an uncertain range response, resend the exact original body/requestId: a retained receipt replays without another mutation, even with the original edit context. | Field | Type | Description | | --- | --- | --- | | `name` | string | 1–200 characters. | | `amount` | integer | Cents (minor units), ≥ 1. | | `categoryInput` | string \| object \| null | Omit to preserve the category; send null to clear it within the selected edit scope. An existing ID or legal local draft assigns a category. | | `recipientInput` | string \| UUID \| null | UUID, new name, or `null` to clear. | | `description` | string \| null | Max 1000 characters. `null` to clear. | | `expenseDate` | integer | Unix timestamp in seconds. | | `occurrenceDate` | integer | Unix seconds for the selected occurrence only, independently of `editScope`. Do not combine with `expenseDate`. | | `schedule` | object \| null | Replace schedule. `null` converts recurring to one-time. | | `forecastSettings` | object | Series-wide variable bill forecasts with `ALL_INSTANCES`. See [fields](https://getfiga.com/help/developers/api/#bill-forecasts). | | `recurringSettings` | object | Fixed/variable monthly settings with `FUTURE_INSTANCES`. See [fields and scope](https://getfiga.com/help/developers/api/#recurring-billing-settings). | | `editScope` | string | Recurring only. See below. | ### Add earlier recurring history Send `range: { start }` to the same PUT, with the `seriesContext` from a fresh expense detail and a new UUID `requestId`. The start accepts a valid YYYY-MM-DD or integer Unix seconds within reporting years 1970–2099 in the series timezone. Monthly lists and totals support reading the added history from 1970. It is normalized to the first term on or after that boundary using the existing recurrence rule. It applies to the entire family, independently of `editScope`. The current release supports daily, weekly, monthly, quarterly and yearly families, including interval and weekday patterns, with date, count or no end. Lifecycle history retains its restrictions on active count. Both backfill and lower-boundary changes support dated method history, with the inheritance and protection rules below. Variable amounts keep their existing monthly-only configuration. The original calendar and date mode must survive normalization; an unprovable backfill returns SERIES\_RULE\_NOT\_PRESERVED without saving. For example, changing 3 January 2026 to 3 January 2025 adds the 2025 terms. Existing confirmed amounts, payments, bill periods, manual dates, skipped and deleted occurrences stay unchanged. New fixed terms are unpaid; unknown variable terms are incomplete until explicitly confirmed. No payment or bill is recorded automatically. ``` { "range": { "start": "2025-01-03" }, "seriesContext": "series-v1:...", "requestId": "5dcbfc0a-c745-4e9d-81e0-3af6dc8c09b4" } ``` `range` may share one atomic PUT with `occurrenceDate`, metadata and tags, alongside `seriesContext`, `requestId` and an unchanged raw `schedule`. The range applies to the family and occurrenceDate to the selected occurrence; `editScope` applies to the other fields. FUTURE uses the original scheduled date, even if the expense date moves. A retained stored document may be edited before the new start. An explicit edit of an occurrence that disappears or is excluded rejects the whole save; ALL/FUTURE metadata may still use its original boundary without materializing it. `forecastSettings` still requires `editScope: ALL_INSTANCES`. Rhythm, method and whole-period amount changes give 400 `SERIES_COMPOSITION_UNSUPPORTED`. A fixed occurrence amount may be edited with explicit THIS\_INSTANCE, subject to the existing money guards. Combining occurrenceDate with legacy expenseDate is invalid. Failure rolls back every part, including new categories/tags; retries cover the complete PUT. The editable end can be changed as described below. Extending before the anchor also supports dated method history: the prefix inherits the first period’s fixed amount or variable strategy/start amount, while later boundaries stay unchanged. For example, an explicit first period of 180 USD overrides a legacy default of 250 USD. A retained document whose billing settings would change causes 409 `SERIES_HISTORY_CONFLICT`, even when its amount is equal. Actual method-history or `variableFrom` changes advance bill settings revision once; lower-boundary edits alone do not. Refetch before a new confirmation after a revision conflict; completed identical bill retries remain idempotent. Fixed historical amounts enter forecasts only after explicit historical confirmation, including after a verified payment; different original currencies, skips and deleted sources remain excluded. An unsupported calendar gives `SERIES_RANGE_UNSUPPORTED`; services require their own bill operation. Missing request ID is 400 `SERIES_REQUEST_ID_REQUIRED`; missing/stale context is 409 `SERIES_CONTEXT_REQUIRED` or `SERIES_CONTEXT_CONFLICT`. Calendar preview proves the dates, not all write-time admission checks. Existing plan limits and the separate financial projection work limit can still refuse the save with no partial mutation. A combined range and forecast save first inherits the prefix settings, then applies forecast ALL to every resulting variable period and the root. Fixed amounts stay unchanged. Omit strategy to keep each period’s strategy; a null start amount is invalid while the root or any remaining variable period is manual. Both expected revisions refer to the state before the save. The whole operation advances bill settings revision once, including an explicit forecast no-op, and returns one range receipt. An unchanged range does not advance range revision. Failure rolls back both parts and their required audits; confirmed amounts and first-confirmation forecasts remain unchanged. Legacy compatibility change: replacing only `schedule.startDate` now changes the series range, preserving recorded occurrence dates and money. Send the complete raw `schedule`, explicit `editScope: ALL_INSTANCES`, and top-level `seriesContext`/`requestId`. Read the expense first; its raw schedule belongs to `scheduleSourceTemplateId`. This adapter accepts only the earliest segment. A child start edit returns `SERIES_RANGE_TARGET_REQUIRED`; use `range` from that same occurrence. Omitted/THIS/FUTURE scope returns `SERIES_RANGE_SCOPE_REQUIRED`. Older clients without context/requestId receive an explicit error; the API never supplies those values automatically. An unchanged raw schedule is a no-op, including when the visible start is later. Raw January plus a June lower boundary and a legacy March start moves the boundary to March, leaving the January anchor. For a January/March/May rhythm, a February start normalizes to March. Preserve every raw end field: omitting one changes the end, and start+end must use `range`. Actual rhythm or timezone changes use the existing guarded rebase; changing the start representation between ISO and Unix returns `SERIES_DATE_MODE_CHANGE_UNSUPPORTED`. The direct template endpoint refuses start-only writes. Legacy `expenseDate` ALL/FUTURE edits keep their existing scope and money protections. After reading the expense, send e.g. `{ schedule: { ...expense.schedule, startDate: "2025-01-03" }, editScope: "ALL_INSTANCES", seriesContext: expense.seriesContext, requestId: newUuid }` when its raw start is ISO. Use Unix seconds for a numeric raw start. On a context conflict, read again and submit the reviewed change with a new request ID. On an uncertain response, resend the identical original body and request ID; do not replace its context. Success returns `data.rangeOperation`, including on replay after the selected virtual term disappears. A changed body with the same ID returns `SERIES_REQUEST_ID_CONFLICT`. The optional `Idempotency-Key` must equal the body request ID. Moving forward stores a lower generation boundary, without rewriting the raw `schedule.startDate`, amounts or method history. Sending the original start in `range` removes that filter; resending an unchanged raw schedule does not. Details expose the whole family’s `effectiveStartDate` and `effectiveStartDateMode` (`iso` or `unix`), independent of the opened segment. Use that mode to display the returned start; the selected segment may use a different date representation. Saved documents before the boundary remain available for permitted confirmation, payment, editing and deletion. Earlier virtual IDs cannot create new documents. If the selected virtual term leaves the range, the first success returns the root as `data.expense` and `selection.kind=series` with its `resultExpenseId`; a replay still succeeds without recreating the term. For a permanently ended series, details expose `permanentEndDate` (YYYY-MM-DD in the series root timezone) separately from the editable `effectiveEnd`. The App displays that permanent end as read-only and omits `range.end` when changing the start. Start-only edits preserve pauses, lifecycle exclusions and the permanent end whether it is in the past or future. The first nominal term must remain on or before that end; no new term can generate or materialize after it. Every explicit end, even the same date or a shorter end, returns `EXPENSE_LIFECYCLE_CONFLICT`. An explicit count end is refused while an uncanceled pause remains, preserving the ability to resume or cancel that pause. Active count together with a permanent end also refuses the edit; date/none family overlays deactivate raw count limiters. A naturally expired schedule without `endedAfter` is still editable. Services retain `BILL_OPERATION_REQUIRED`. While a lower boundary or a lower-plan exclusion is active, legacy FUTURE deletion and conversion return 409 `EXPENSE_LIFECYCLE_CONFLICT` before changing any document. Use the series end action where supported; count-based series can change their editable end through the range operation. Changing the end preserves recorded documents and is not bulk deletion. Individual deletion and permitted whole-series deletion retain their own guards. Legacy yearly projections return `BILL_READ_UNSUPPORTED`; use canonical unified statistics. An optional `Idempotency-Key` header must equal the body UUID; it does not replace it. On an uncertain response, resend exactly the same target and payload with the same ID. The durable receipt is checked before the old context. Reusing the ID for different input returns 409 `SERIES_REQUEST_ID_CONFLICT`. Current workspace permission and plan access are checked on every replay. For a supported family with multiple versions, `range.end` date/count/none applies to the whole family without deleting versions or saved documents. Omission preserves the current end and its ownership. The first explicit end stores a root-owned `generationEnd`; null keeps each legacy segment’s limits, whereas explicit none removes their effect. Later metadata or rhythm edits retain that family end. Activation that would fill an existing interior calendar gap fails with `SERIES_HISTORY_CONFLICT`. A changed raw end then fails with `SERIES_COMPOSITION_UNSUPPORTED`; use `range.end`. Destructive FUTURE deletion/conversion fails with `EXPENSE_LIFECYCLE_CONFLICT`, including with explicit none. A family count stores nominal positions across all segments from the physical start, before the lower boundary, skips and deleted documents. Its effective count starts at the normalized lower boundary. This remains true if ALL later collapses the versions; no separate count is copied into each child. For a series with a count end, `effectiveOccurrenceCount` is the raw count minus nominal terms before the lower boundary. Skips and deleted documents still consume nominal positions; this is not `commitment.totalOccurrences`, which counts active charges. For a supported series, send `range: { end: { type: "count", value: 10 } }` to set the effective count. You may combine it with `range.start`; the count then starts at the final normalized first term. The App uses the same operation for its occurrence-count control. Example: raw start 3 January 2026 and count 12 end on 3 December 2026. Moving the start to 3 June shows 7 terms and retains raw 12. Entering 10 effective terms stores raw 15 and ends on 3 March 2027. Starting again from the original raw 12, moving the start back to January 2025 without an `end` stores raw 24 and retains December 2026: omitted end preserves the last date, not the visible number. Raw `schedule` fields remain raw; an unchanged raw count is a no-op. Family example: monthly terms fall on the 3rd from January through May, then on the 8th from June. A count of 8 ends on 8 August. Moving the start to 1 June normalizes it to 8 June, shows 3 remaining terms, and keeps the August end. Entering 5 then stores raw 10 and ends on 8 October. Omitted end preserves that last date when backfilling. Active count does not support pause/end lifecycle actions; edit the range end instead. The same `range` accepts `end: { type: "date", value: "2026-08-15" }`, `end: { type: "count", value: 4 }`, or `end: { type: "none" }`. A date includes that entire calendar day but never creates an off-rhythm term: a series due on the 3rd and ending on 15 August has its last term on 3 August. Date input uses the same reporting bounds as start. A count begins at the final normalized start; none removes both editable limiters. Omitted end preserves the existing end type and last scheduled date. The App exposes these same end controls for supported series, including those with dated method history; its rhythm restrictions remain unchanged. Details expose backend-resolved `effectiveEnd` as date (the selected raw ISO date or Unix seconds, preserving its calendar mode), count (effective nominal count), or none. Existing raw `endDate` and `endAfter` date forms keep their original representation on reads and start-only changes. Older stored calendars with both limiters use the earlier restriction; reads never rewrite them. An unchanged raw PUT remains a no-op. New or genuinely changed raw schedules require one limiter; explicit `range.end` for a single version without a family overlay stores one canonical end (date as `endDate`, count as `endAfter`, none removes both). A family overlay retains the raw segment fields and replaces their effect instead. A changed raw end combined with range gives 400 `SERIES_COMPOSITION_UNSUPPORTED`. A permanent lifecycle end cannot be changed by this operation and returns 409 `EXPENSE_LIFECYCLE_CONFLICT`. The stored count must remain within 1–1000 after translation. Effective 10 plus 995 earlier nominal terms would require raw 1005, so preview and commit refuse with 400 `SERIES_RANGE_COUNT_LIMIT` and explain the calculation. A start after the last term gives 400 `SERIES_RANGE_EMPTY`. Neither refusal saves anything. The 2100 calendar-proof boundary does not truncate nominal counts whose last term is later; explicit input dates still obey the reporting-date limits. Existing raw anchors before 1970 also count in the nominal prefix; `effectiveStartDate` may report such an inherited date without allowing a new start outside the input limits. The first success returns `data.expense` and `data.rangeOperation`. The latter contains `requestId`, `rootId`, `committedContext`, `outcome` (`applied` or `no_change`), and `selection` with `requestedExpenseId`, `resultExpenseId` and `kind` (`occurrence` or `series`). A replay may return only `rangeOperation`. Refetch `resultExpenseId` for current data; the receipt is evidence of the completed operation, not a fresh expense snapshot. Receipts live with the recurring family, independently of audit retention and transport caches. Soft deletion retains them; permanent family/workspace/personal-account deletion removes them. MCP `figa_update_expense` accepts the same range contract and copies its outer `requestId` into the shared operation. If `changes.requestId` is supplied, it must match. Durable receipt replay remains available after the 24-hour MCP response cache expires, subject to current access and plan limits. The deprecated template, instance, materialization and bulk APIs do not accept these fields. The App sidebar obtains its summary from the read-only session endpoint `POST /api/v1/workspaces/:workspaceId/expenses-unified/:expenseId/range-preview`, with `{ range, seriesContext }` and optional `forecastSettings` plus `editScope: ALL_INSTANCES`. Combined previews validate the same forecast rules and show the resulting variable-prefix settings. Its `data.rangePreview` contains the normalized `effectiveStartDate` and its mode, `extendsHistory` (whether the operation adds a prefix), `effectiveEnd`, `effectiveOccurrenceCount`, `inheritedSettings`, `excludedPlanCandidates` with each document’s UUID, scheduled date and its `scheduledDateMode`, expense date, protection and selected state, and `complete: true` only after a complete proof. It creates no documents or receipt and does not reserve the write; PUT revalidates. This is separate from a lifecycle `previewToken`. `range.excludePlanIds` optionally selects recorded plans before the resulting first term. Omit it to preserve existing lower-boundary markings, send a UUID array to replace only those markings, or send `[]` to clear them. It may be the only field in `range`. Nothing is selected automatically. Confirmed invoices and Paid expenses cannot be excluded; archived payments alone do not protect an Unpaid plan: commit returns 409 `SERIES_PLAN_PROTECTED` without a partial save. This includes reactivating an old marking after the restored expense was paid or confirmed; remove that marking explicitly. The preview shows such a retained selection as protected so it can be removed. For example, moving the first term from January to June preserves a recorded January plan unless its UUID is explicitly selected. Moving the first term back to January restores that same document, with its attachments and manual expense date. Skips and deletion remain in force. Excluded documents cannot be edited, paid or materialized through old IDs. These markings do not change pause/end history. The exclusion preview reads at most 500 recorded documents in the whole family, not 500 selections. A 501st document returns 409 `VIRTUAL_INSTANCE_GENERATION_LIMIT_EXCEEDED`; no partial list is presented as complete. PUT repeats completeness and protection checks under locks. Splitting the selection into smaller requests does not bypass the document limit. ### editScope: recurring expense edits For example, editing November’s occurrence with `occurrenceDate` set to 8 December moves only that document. Its canonical `scheduledDate`, invoice period, payments and financial snapshots remain unchanged; December’s regular occurrence stays separate. Other fields in the same request retain their selected scope. Dates must fit both the generator domain and reporting years 1970–2099 in the stored series timezone. Conflicting date fields or a financial guard failure roll back the entire update. Legacy `expenseDate` retains its THIS/FUTURE/ALL behavior. The new field is available through this API and MCP `figa_update_expense` in `changes.occurrenceDate`. `currency` and `isPaid` are not expense PUT fields. Keep the original currency and use payment operations to record money paid. When updating or deleting a recurring expense, `editScope` controls which occurrences are affected: | Value | Effect | | --- | --- | | `THIS_INSTANCE` | Only the specific occurrence. Creates a materialized override. | | `FUTURE_INSTANCES` | This occurrence and all future occurrences. | | `ALL_INSTANCES` | Entire series (past + future). Updates the template directly. | ### Update single occurrence of a recurring expense ``` curl -X PUT https://api.figa.cc/api/v1/expenses/{expenseId} \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "amount": 450000, "editScope": "THIS_INSTANCE" }' ``` ### Update all future occurrences ``` curl -X PUT https://api.figa.cc/api/v1/expenses/{expenseId} \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "amount": 450000, "editScope": "FUTURE_INSTANCES" }' ``` ## List expenses: query parameters `GET /api/v1/expenses` · Permission: `expenses.read` | Param | Type | Required | Description | | --- | --- | --- | --- | | `year` | integer | Yes | Year (2000–2100). | | `month` | integer | Yes | Month (1–12). | | `includeTemplates` | boolean | No | Include recurring templates. Default: `true`. | | `showPaidOnly` | boolean | No | Only paid expenses. Default: `false`. | | `showUnpaidOnly` | boolean | No | Only unpaid expenses. Default: `false`. | | `categoryId` | UUID | No | Filter by category. | | `recipientId` | UUID | No | Filter by recipient. | | `limit` | integer | No | Max results (1–50). | ### List unpaid expenses for February 2026 ``` curl -X GET "https://api.figa.cc/api/v1/expenses?year=2026&month=2&showUnpaidOnly=true" \ -H "x-api-key: et_live_abc123..." ``` ## Delete expense `DELETE /api/v1/expenses/:expenseId` · Permission: `expenses.delete` For recurring expenses, pass `editScope` as a query parameter to control what gets deleted: ``` # Delete single occurrence curl -X DELETE "https://api.figa.cc/api/v1/expenses/{expenseId}?editScope=THIS_INSTANCE" \ -H "x-api-key: et_live_abc123..." # Delete entire recurring series curl -X DELETE "https://api.figa.cc/api/v1/expenses/{expenseId}?editScope=ALL_INSTANCES" \ -H "x-api-key: et_live_abc123..." ``` ## Set Paid or Unpaid `PUT /api/v1/expenses/:expenseId/payment-status` · Permission: `expenses.payments` Read the expense detail first. Send the desired `isPaid`, its `editContext` as `expectedEditContext`, and `paymentStatusRevision` as `expectedPaymentStatusRevision`. A confirmed bill also requires `expectedBillRevision`. Copy the returned context unchanged; never construct it or silently bind an old command to a fresh read. ``` { "isPaid": true, "expectedEditContext": "COPY_FROM_EXPENSE_DETAIL", "expectedPaymentStatusRevision": 3, "expectedBillRevision": 2, "paymentDate": 1739577600 } ``` The example revisions are placeholders. Omit `expectedBillRevision` for an ordinary non-bill expense. Optional `paymentDate` uses Unix seconds and defaults to now only on a real Unpaid → Paid transition. Repeating Paid with fresh expectations preserves its known or unknown date; Unpaid clears the current date. Only a real transition advances the status revision. No `amount`, `paymentAmount`, method or notes are accepted, and no payment-history row is created or removed. Unknown, estimated or skipped bills cannot become Paid before legal confirmation/restoration. Use [atomic confirmation with markPaid](https://getfiga.com/help/developers/api/#confirm-bill) to save an actual amount and set Paid together. A later correction from 100 to 80 or 120 preserves status and date; it does not edit the archive. Keep a UUID `Idempotency-Key` and the whole payload unchanged for an uncertain retry within the existing 24-hour cache. A conflict requires a fresh read and a reviewed new intent. Replay may return an earlier receipt; GET the expense for current status before reporting success. After a later Unpaid, replay cannot restore Paid, including after cache expiry. Old POST/DELETE payment mutations and legacy amount writers return `410 LEGACY_PAYMENT_OPERATION_REMOVED`, with the replacement operation. A stale App card must refresh; it cannot report an old payment as success. ## Read archived payments and current totals `GET /api/v1/expenses/:expenseId/payments` · Permission: `expenses.read` The archive remains readable and exportable. Each row keeps its currency-labelled amount, base snapshot and `currencySemantics`. Current `totalPaid`/`remainingAmount` use the expense’s original currency and its binary status: the whole known amount belongs to one side. The base pair uses the current stored base valuation. Unknown valuations stay null. Archived rows do not create a current partial balance. For example, an Unpaid 100 USD expense valued at 410 PLN with a historical 25 USD payment returns: ``` { "payments": [{ "amount": 2500, "currency": "USD", "baseAmountMinor": 10250, "baseCurrency": "PLN", "currencySemantics": "explicit" }], "metadata": { "totalPaid": 0, "remainingAmount": 10000, "currency": "USD", "baseTotalPaid": 0, "baseRemainingAmount": 41000, "baseCurrency": "PLN", "archivedTotalPaid": 2500, "archivedCurrency": "USD", "currencySemantics": "explicit", "paymentCount": 1 } } ``` Missing historical base values do not invalidate a complete current expense valuation. `currencySemantics` describes the archive; legacy ambiguous rows retain their labelled raw value. When archived row currencies differ, `archivedTotalPaid` and `archivedCurrency` are null. Never add different currencies or fill missing historical FX with today’s rate. ## Monthly totals: query parameters `GET /api/v1/expenses/monthly-totals` · Permission: `expenses.read` | Param | Type | Required | Description | | --- | --- | --- | --- | | `startYear` | integer | Yes | Starting year (2000–2100). | | `startMonth` | integer | Yes | Starting month (1–12). | | `months` | integer | No | Number of months to return (1–12). Default: `7`. | ``` curl -X GET "https://api.figa.cc/api/v1/expenses/monthly-totals?startYear=2026&startMonth=1&months=6" \ -H "x-api-key: et_live_abc123..." ``` ## Bulk actions `POST /api/v1/expenses/bulk` · Permission: `expenses.write` · HTTP 207 with per-item results. Supported actions are `markAsPaid`, `markAsUnpaid` and `delete`, with 1–100 IDs. Status actions require `expectations[id]` copied from each reviewed expense detail, including the confirmed bill revision where applicable. Missing/stale expectations fail that item; successful items remain committed. A fresh no-op is skipped. Unpaid preserves archived payments. ``` { "action": "markAsPaid", "ids": ["EXPENSE_ID"], "expectations": { "EXPENSE_ID": { "expectedEditContext": "COPY_FROM_EXPENSE_DETAIL", "expectedPaymentStatusRevision": 0 } }, "payload": { "paymentDateMode": "expenseDate" } } ``` `paymentDateMode: "expenseDate"` selects each current expense date under locks. Alternatively send one `paymentDate`, or omit both to use now. Combining both is invalid. `paymentMethod` belongs to the retired payment model and is refused. This API contract does not enable a disabled bulk feature in the App. ## Skip / restore occurrence `POST /api/v1/expenses/:expenseId/skip/toggle` · Permission: `expenses.write` Toggle the skip status of a single recurring occurrence. Only unpaid instances can be skipped. Skipped instances remain visible but are excluded from totals. | Field | Type | Description | | --- | --- | --- | | `scheduledDate` | integer \| string | Occurrence identifier: Unix timestamp (seconds) or ISO date `YYYY-MM-DD`. | ### Skip using Unix timestamp ``` curl -X POST https://api.figa.cc/api/v1/expenses/{expenseId}/skip/toggle \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{"scheduledDate": 1740787200}' ``` ### Skip using ISO date (recommended for automations) ``` curl -X POST https://api.figa.cc/api/v1/expenses/{expenseId}/skip/toggle \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{"scheduledDate": "2026-03-30"}' ``` If no matching occurrence exists, API returns `404` (for both timestamp and ISO date). ## Idempotency POST mutations support the `Idempotency-Key` header (UUID format). If the same key is sent again within 24 hours, the server returns the cached response instead of processing the request again, including a completed 5xx response. Bill confirmation/forecast and service-calculation PUTs also support this header. Other existing PUT/DELETE routes do not cache a supplied idempotency key. ``` curl -X POST https://api.figa.cc/api/v1/expenses \ -H "x-api-key: et_live_abc123..." \ -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \ -H "Content-Type: application/json" \ -d '{"name":"AWS","amount":14250,"categoryInput":"Cloud"}' ``` **Idempotency is optional** Without the header, requests are processed normally. The header is recommended for automation integrations where retries are common. Use a fresh UUID per new operation and retain it for retries. Reusing it for a different body or endpoint returns `IDEMPOTENCY_KEY_MISMATCH` (409). Pending duplicates return `IDEMPOTENT_REQUEST_IN_PROGRESS` (409). An interrupted request may have committed: inspect the resource after an uncertain result, including `IDEMPOTENCY_OUTCOME_UNKNOWN`, before sending another mutation with a new key. Replay protection has a 24-hour lifetime; it is not an unlimited exactly-once guarantee. ## Unavailable to workspace API keys Account/security settings, whole-account exports, organization/workspace management, membership, invitations, billing, key management, admin/console/Pulse, UI locks and global category/recipient mutations are not authorized by a workspace API key. Figa AI is not an API capability. Attachment transfer and CSV import are not exposed through this API; structured expense creation and bulk actions are available. Notification reads are workspace-scoped; personal notification settings and read/dismiss actions remain app-only. ## Error handling | Status | Meaning | Action | | --- | --- | --- | | `400` | Validation error | Fix request payload or query params. Response body contains field-level errors. | | `401` | Unauthorized | Check API key is valid and not expired. | | `403` | Forbidden | Key lacks required permission or route not in allowlist. | | `404` | Not found | Resource ID does not exist or is not accessible. | | `409` | Conflict | Duplicate name, plan limit reached, or concurrent idempotent request. | | `429` | Rate limited | Wait for the Retry-After header before retrying. | | `5xx` | Server error | A replay returns the same result. Read the resource to resolve an uncertain outcome; do not blindly submit a new mutation. | **Troubleshooting 403 / Cloudflare blocks** Distinguish a JSON permission/plan error from an edge challenge page. Keep the timestamp and request/Ray ID for support when Cloudflare blocks a call. A browser challenge needs an edge configuration fix; changing API keys or blindly retrying will not resolve it. **About timestamps** All date fields (`expenseDate`, `paymentDate`, `scheduledDate`, `startDate` as integer) are Unix timestamps in **seconds** (not milliseconds). String dates accept ISO 8601 format (`YYYY-MM-DD`). The App’s CSV importer accepts a missing `category` column or an empty cell as no category, whether category auto-creation is on or off. A nonempty unknown name is created only when auto-creation is enabled; otherwise that row fails. CSV still supports one-time expenses and fixed recurring templates, not variable bills or services. Account exports preserve `categoryId: null` in JSON and an empty categoryId cell in CSV. The account archive is a historical export, not the CSV importer’s input format. --- Source: https://getfiga.com/help/developers/api-schedule/ # Recurring schedule reference Adding a `schedule` object to the expense creation payload turns a one-time expense into a recurring template. The engine generates virtual instances automatically for each month view. [← Back to API reference](https://getfiga.com/help/developers/api) ## Schedule object fields | Field | Type | Default | Description | | --- | --- | --- | --- | | `frequency` | string | None | **Required.** One of: `once`, `daily`, `weekly`, `monthly`, `quarterly`, `yearly`. | | `startDate` | string \| integer | None | **Required.** ISO date (`"2026-03-01"`) or Unix seconds (`1740787200`). | | `endDate` | string \| integer | none | Hard end date. Cannot be combined with `endAfter`. | | `dayOfMonth` | integer | none | Day of month (1–31). Used with `monthly` / `quarterly`, or paired with `monthOfYear` for `yearly`. | | `monthOfYear` | integer | none | Month 1–12. Only for `yearly`, together with `dayOfMonth`. | | `dayOfWeek` | integer | none | Day of week (0 = Sunday … 6 = Saturday). Used with `weekly` or `monthly`+`weekOfMonth`. | | `daysOfWeek` | integer\[\] | none | Multiple days (e.g. `[1, 3, 5]` = Mon/Wed/Fri). `weekly` only. | | `weekOfMonth` | integer | none | Week number (1–5). Requires `dayOfWeek`. Used with `monthly` / `quarterly`. | | `interval` | integer | `1` | Repeat every N periods (1–100). E.g. `2` with `weekly` = every 2 weeks. | | `endAfter` | object | none | End condition. Cannot be combined with `endDate`. See below. | | `timezone` | string | `"Europe/Warsaw"` | IANA timezone for occurrence calculation. | ### endAfter object | type | value | Description | | --- | --- | --- | | `"count"` | integer (1–1000) | Stop after N total occurrences. | | `"date"` | ISO date or Unix seconds | Stop on/after this date. | **End conditions are mutually exclusive** You can use `endDate` **or** `endAfter`, but **not both**. Omit both for an open-ended (infinite) recurring schedule. ## Required fields by frequency | frequency | Required extras | Allowed optional | Forbidden | | --- | --- | --- | --- | | `once` | none | none | dayOfMonth, dayOfWeek, daysOfWeek, weekOfMonth, interval ≠ 1 | | `daily` | none | interval | dayOfMonth, dayOfWeek, daysOfWeek, weekOfMonth | | `weekly` | `dayOfWeek` or `daysOfWeek` | interval | dayOfMonth, weekOfMonth | | `monthly` | `dayOfMonth` _or_ (`weekOfMonth` + `dayOfWeek`) | interval | daysOfWeek | | `quarterly` | `dayOfMonth` _or_ (`weekOfMonth` + `dayOfWeek`) | interval | daysOfWeek | | `yearly` | none (legacy startDate rule) | interval, monthOfYear + dayOfMonth | daysOfWeek | **weekOfMonth always requires dayOfWeek** To express patterns like “first Monday” or “third Friday”, you must provide **both** `weekOfMonth` and `dayOfWeek`. ## frequency: once A single scheduled occurrence at `startDate`. Useful for a future-dated expense that should appear on its due date. ``` curl -X POST https://api.figa.cc/api/v1/expenses \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "name": "Annual insurance premium", "amount": 240000, "categoryInput": "Insurance", "schedule": { "frequency": "once", "startDate": "2026-06-15" } }' ``` ## frequency: daily ### Every day ``` "schedule": { "frequency": "daily", "startDate": "2026-03-01" } ``` ### Every 3 days ``` "schedule": { "frequency": "daily", "startDate": "2026-03-01", "interval": 3 } ``` ### Every day for 30 days ``` "schedule": { "frequency": "daily", "startDate": "2026-03-01", "endAfter": { "type": "count", "value": 30 } } ``` ### Every day until end of year ``` "schedule": { "frequency": "daily", "startDate": "2026-03-01", "endDate": "2026-12-31" } ``` ## frequency: weekly ### Every Friday ``` "schedule": { "frequency": "weekly", "startDate": "2026-03-06", "dayOfWeek": 5 } ``` **dayOfWeek values** `0` = Sunday, `1` = Monday, `2` = Tuesday, `3` = Wednesday, `4` = Thursday, `5` = Friday, `6` = Saturday. ### Every other Monday ``` "schedule": { "frequency": "weekly", "startDate": "2026-03-02", "dayOfWeek": 1, "interval": 2 } ``` ### Monday, Wednesday, Friday every week ``` "schedule": { "frequency": "weekly", "startDate": "2026-03-02", "daysOfWeek": [1, 3, 5] } ``` ### Tuesday and Thursday, every 2 weeks, 20 occurrences ``` "schedule": { "frequency": "weekly", "startDate": "2026-03-03", "daysOfWeek": [2, 4], "interval": 2, "endAfter": { "type": "count", "value": 20 } } ``` ### Full curl: weekly team lunch ``` curl -X POST https://api.figa.cc/api/v1/expenses \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "name": "Team lunch", "amount": 15000, "categoryInput": "Food", "recipientInput": "Pizza Place", "schedule": { "frequency": "weekly", "startDate": "2026-03-06", "dayOfWeek": 5 } }' ``` ## frequency: monthly ### 1st of every month (rent, subscriptions) ``` "schedule": { "frequency": "monthly", "startDate": "2026-01-01", "dayOfMonth": 1 } ``` ### 15th of every month ``` "schedule": { "frequency": "monthly", "startDate": "2026-01-15", "dayOfMonth": 15 } ``` ### Last day of month (dayOfMonth: 31) ``` "schedule": { "frequency": "monthly", "startDate": "2026-01-31", "dayOfMonth": 31 } ``` **dayOfMonth: 31 in short months** When `dayOfMonth` exceeds the number of days in a month (e.g. 31 in February), the occurrence is placed on the last day of that month. ### Every other month on the 10th ``` "schedule": { "frequency": "monthly", "startDate": "2026-01-10", "dayOfMonth": 10, "interval": 2 } ``` ### First Monday of every month ``` "schedule": { "frequency": "monthly", "startDate": "2026-01-06", "weekOfMonth": 1, "dayOfWeek": 1 } ``` ### Third Friday of every month ``` "schedule": { "frequency": "monthly", "startDate": "2026-01-16", "weekOfMonth": 3, "dayOfWeek": 5 } ``` ### 12 monthly installments (loan repayment) ``` "schedule": { "frequency": "monthly", "startDate": "2026-01-01", "dayOfMonth": 1, "endAfter": { "type": "count", "value": 12 } } ``` ### Monthly until December 2027 ``` "schedule": { "frequency": "monthly", "startDate": "2026-01-01", "dayOfMonth": 1, "endDate": "2027-12-31" } ``` ### Full curl: monthly rent ``` curl -X POST https://api.figa.cc/api/v1/expenses \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "name": "Office rent", "amount": 420000, "categoryInput": "Housing", "recipientInput": "WeWork", "description": "Monthly office lease", "currency": "PLN", "schedule": { "frequency": "monthly", "startDate": "2026-01-01", "dayOfMonth": 1 } }' ``` ### Full curl: 36 installments (phone lease) ``` curl -X POST https://api.figa.cc/api/v1/expenses \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "name": "iPhone lease", "amount": 12500, "categoryInput": "Equipment", "recipientInput": "Apple", "schedule": { "frequency": "monthly", "startDate": "2026-02-15", "dayOfMonth": 15, "endAfter": { "type": "count", "value": 36 } } }' ``` ## frequency: quarterly ### 1st of each quarter ``` "schedule": { "frequency": "quarterly", "startDate": "2026-01-01", "dayOfMonth": 1 } ``` ### 15th of each quarter ``` "schedule": { "frequency": "quarterly", "startDate": "2026-01-15", "dayOfMonth": 15 } ``` ### First Monday of each quarter ``` "schedule": { "frequency": "quarterly", "startDate": "2026-01-05", "weekOfMonth": 1, "dayOfWeek": 1 } ``` ### Full curl: quarterly tax advance ``` curl -X POST https://api.figa.cc/api/v1/expenses \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "name": "VAT advance payment", "amount": 850000, "categoryInput": "Tax", "recipientInput": "Urząd Skarbowy", "schedule": { "frequency": "quarterly", "startDate": "2026-01-25", "dayOfMonth": 25 } }' ``` ## frequency: yearly ### Yearly on start date anniversary ``` "schedule": { "frequency": "yearly", "startDate": "2026-06-15" } ``` Without `monthOfYear`, the yearly month and day come from `startDate`; a legacy `dayOfMonth` alone remains ignored. With `monthOfYear` (1–12), `dayOfMonth` (1–31) is required and defines the yearly date. The start still determines the interval phase and earliest generated term. The pair is available through the same schedule schema in the session API, API-key API and existing MCP schedule edits. ### Every 2 years ``` "schedule": { "frequency": "yearly", "startDate": "2026-06-15", "interval": 2 } ``` ### Preserve February 29 after extending history ``` { "frequency": "yearly", "startDate": "2023-03-01", "monthOfYear": 2, "dayOfMonth": 29 } ``` This produces March 1 in 2023 and February 29 in 2024 and 2028. February 29 overflows to March 1 in non-leap years, preserving the existing yearly rule. A range backfill from a legacy February 29 anchor records this pair automatically. Reading an old schedule does not activate previously ignored fields. ### Full curl: yearly domain renewal ``` curl -X POST https://api.figa.cc/api/v1/expenses \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "name": "figa.io domain renewal", "amount": 4500, "categoryInput": "Infrastructure", "recipientInput": "Cloudflare", "currency": "USD", "schedule": { "frequency": "yearly", "startDate": "2026-09-12" } }' ``` ## Managing recurring expenses To change fixed/variable monthly billing from an occurrence, use [`recurringSettings`](https://getfiga.com/help/developers/api#recurring-billing-settings). Save calendar changes separately. Schedule changes are unavailable for series with billing-method history. ### Read schedule details ``` curl -X GET https://api.figa.cc/api/v1/expenses/{expenseId} \ -H "x-api-key: et_live_abc123..." ``` Returns the full expense object with `schedule`, `occurrences` array, and `stats` (totalOccurrences, paidOccurrences, progress, etc.). ### Read a single occurrence ``` curl -X GET "https://api.figa.cc/api/v1/expenses/{expenseId}?occurrence=1740787200" \ -H "x-api-key: et_live_abc123..." ``` Pass the occurrence's scheduled Unix timestamp to get that specific instance. ### Change schedule for entire series ``` curl -X PUT https://api.figa.cc/api/v1/expenses/{expenseId} \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "schedule": { "frequency": "monthly", "startDate": "2026-01-05", "dayOfMonth": 5 }, "editScope": "ALL_INSTANCES" }' ``` ### Update amount for this + future occurrences ``` curl -X PUT https://api.figa.cc/api/v1/expenses/{expenseId} \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "amount": 450000, "editScope": "FUTURE_INSTANCES" }' ``` ### Override a single occurrence ``` curl -X PUT https://api.figa.cc/api/v1/expenses/{expenseId} \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "amount": 500000, "description": "Increased rent for March", "editScope": "THIS_INSTANCE" }' ``` ### Skip an occurrence `scheduledDate` accepts Unix seconds or ISO date `YYYY-MM-DD`. #### Using Unix timestamp ``` curl -X POST https://api.figa.cc/api/v1/expenses/{expenseId}/skip/toggle \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{"scheduledDate": 1740787200}' ``` #### Using ISO date (recommended) ``` curl -X POST https://api.figa.cc/api/v1/expenses/{expenseId}/skip/toggle \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{"scheduledDate": "2026-03-30"}' ``` Call again with the same `scheduledDate` to restore a skipped occurrence. Only unpaid instances can be skipped. If occurrence is not found, API returns `404`. ### Convert recurring to one-time ``` curl -X PUT https://api.figa.cc/api/v1/expenses/{expenseId} \ -H "x-api-key: et_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "schedule": null, "editScope": "ALL_INSTANCES" }' ``` ### Delete single occurrence ``` curl -X DELETE "https://api.figa.cc/api/v1/expenses/{expenseId}?editScope=THIS_INSTANCE" \ -H "x-api-key: et_live_abc123..." ``` ### Delete entire series ``` curl -X DELETE "https://api.figa.cc/api/v1/expenses/{expenseId}?editScope=ALL_INSTANCES" \ -H "x-api-key: et_live_abc123..." ``` ## editScope reference When updating (`PUT`) or deleting (`DELETE`) a recurring expense, `editScope` determines which occurrences are affected: | Value | PUT effect | DELETE effect | | --- | --- | --- | | `THIS_INSTANCE` | Materializes and overrides only this occurrence. | Removes only this occurrence. | | `FUTURE_INSTANCES` | Applies changes to this and all future occurrences. | Removes this and all future occurrences. | | `ALL_INSTANCES` | Updates the template (all past + future). | Deletes the entire recurring series. | **editScope is for recurring expenses only** For one-time expenses, omit `editScope`. It is ignored for non-recurring expenses. ## Quick reference: common patterns | Use case | schedule JSON | | --- | --- | | Monthly rent on 1st | `{ "frequency": "monthly", "startDate": "2026-01-01", "dayOfMonth": 1 }` | | Weekly Friday coffee | `{ "frequency": "weekly", "startDate": "2026-01-02", "dayOfWeek": 5 }` | | Quarterly tax (25th) | `{ "frequency": "quarterly", "startDate": "2026-01-25", "dayOfMonth": 25 }` | | Yearly renewal | `{ "frequency": "yearly", "startDate": "2026-09-12" }` | | Bi-weekly Mon payroll | `{ "frequency": "weekly", "startDate": "2026-01-05", "dayOfWeek": 1, "interval": 2 }` | | Mon/Wed/Fri gym | `{ "frequency": "weekly", "startDate": "2026-01-05", "daysOfWeek": [1, 3, 5] }` | | 1st Monday of month | `{ "frequency": "monthly", "startDate": "2026-01-05", "weekOfMonth": 1, "dayOfWeek": 1 }` | | 12 installments | `{ "frequency": "monthly", "startDate": "2026-01-01", "dayOfMonth": 1, "endAfter": { "type": "count", "value": 12 } }` | | Daily until end of year | `{ "frequency": "daily", "startDate": "2026-01-01", "endDate": "2026-12-31" }` | | Every 3 days, 30 times | `{ "frequency": "daily", "startDate": "2026-01-01", "interval": 3, "endAfter": { "type": "count", "value": 30 } }` | --- Source: https://getfiga.com/help/developers/api-insights/ # Insights API reference Five read-only analytics endpoints that compute deterministic aggregations from expense data. All require `expenses.read` permission and accept a workspace-scoped API key. [← Back to API reference](https://getfiga.com/help/developers/api) **No AI / LLM involved** These endpoints return **deterministic calculations** (sums, averages, linear regression). Use them in your own reports, automations, or connected external agents through a workspace API key. ## Summary `GET /api/v1/insights/summary` · Permission: `expenses.read` Spending summary for a single month with category and recipient breakdowns. ### Query parameters | Param | Type | Required | Description | | --- | --- | --- | --- | | `period` | string | Yes | Month in `YYYY-MM` format (e.g. `2026-02`). | ### Example request ``` curl -X GET "https://api.figa.cc/api/v1/insights/summary?period=2026-02" \ -H "x-api-key: et_live_abc123..." ``` ### Response ``` { "period": "2026-02", "total": 854250, "count": 24, "paid": 18, "unpaid": 6, "byCategory": [ { "name": "Housing", "amount": 420000, "count": 1, "pct": 49 }, { "name": "Cloud", "amount": 214250, "count": 5, "pct": 25 }, { "name": "Food", "amount": 120000, "count": 12, "pct": 14 }, { "name": "Software", "amount": 100000, "count": 6, "pct": 12 } ], "byRecipient": [ { "name": "WeWork", "amount": 420000, "count": 1 }, { "name": "AWS", "amount": 142500, "count": 3 }, { "name": "Hetzner", "amount": 71750, "count": 2 } ] } ``` ### Response fields | Field | Type | Description | | --- | --- | --- | | `period` | string | Requested period. | | `total` | integer | Total amount in cents. | | `count` | integer | Total expense count. | | `paid` | integer | Number of paid expenses. | | `unpaid` | integer | Number of unpaid expenses. | | `byCategory[]` | array | Breakdown by category, sorted by amount descending. | | `.name` | string | Category name. | | `.amount` | integer | Total in cents. | | `.count` | integer | Expense count in this category. | | `.pct` | integer | Percentage of total (0–100). | | `byRecipient[]` | array | Breakdown by recipient, sorted by amount descending. | | `.name` | string | Recipient name. | | `.amount` | integer | Total in cents. | | `.count` | integer | Expense count for this recipient. | ## Comparison `GET /api/v1/insights/comparison` · Permission: `expenses.read` Compare two months with absolute/percentage differences and per-category change breakdown. ### Query parameters | Param | Type | Required | Description | | --- | --- | --- | --- | | `p1` | string | Yes | First period in `YYYY-MM` format. | | `p2` | string | Yes | Second period in `YYYY-MM` format (baseline for % calculation). | ### Example request ``` curl -X GET "https://api.figa.cc/api/v1/insights/comparison?p1=2026-02&p2=2026-01" \ -H "x-api-key: et_live_abc123..." ``` ### Response ``` { "p1": { "period": "2026-02", "total": 854250, "count": 24, "paid": 18, "unpaid": 6, "byCategory": [ ... ], "byRecipient": [ ... ] }, "p2": { "period": "2026-01", "total": 790000, "count": 22, "paid": 22, "unpaid": 0, "byCategory": [ ... ], "byRecipient": [ ... ] }, "diff": 64250, "diffPct": 8.1, "categoryChanges": [ { "name": "Cloud", "p1": 214250, "p2": 180000, "diff": 34250, "diffPct": 19.0 }, { "name": "Food", "p1": 120000, "p2": 130000, "diff": -10000, "diffPct": -7.7 }, { "name": "Housing", "p1": 420000, "p2": 420000, "diff": 0, "diffPct": 0 } ] } ``` ### Response fields | Field | Type | Description | | --- | --- | --- | | `p1` | Summary | Full summary object for first period. | | `p2` | Summary | Full summary object for second period (baseline). | | `diff` | integer | Absolute difference in cents (`p1.total − p2.total`). | | `diffPct` | number | Percentage change relative to p2 (1 decimal). | | `categoryChanges[]` | array | Per-category changes, sorted by absolute diff descending. | | `.name` | string | Category name. | | `.p1` | integer | Amount in p1 (cents). | | `.p2` | integer | Amount in p2 (cents). | | `.diff` | integer | Difference in cents. | | `.diffPct` | number | Percentage change (1 decimal). | ## Trends `GET /api/v1/insights/trends` · Permission: `expenses.read` Multi-month trend analysis with linear regression. Returns overall direction and per-category trends. ### Query parameters | Param | Type | Required | Description | | --- | --- | --- | --- | | `months` | integer | No | Number of months to analyze (2–24). Default: `6`. | ### Example request ``` curl -X GET "https://api.figa.cc/api/v1/insights/trends?months=12" \ -H "x-api-key: et_live_abc123..." ``` ### Response ``` { "months": [ { "period": "2025-03", "total": 680000 }, { "period": "2025-04", "total": 720000 }, { "period": "2025-05", "total": 710000 }, { "period": "2025-06", "total": 780000 }, { "period": "2025-07", "total": 810000 }, { "period": "2025-08", "total": 854250 } ], "avgMonthly": 759042, "trend": "up", "trendPct": 8.4, "categoryTrends": [ { "name": "Cloud", "trend": "up", "trendPct": 15.2 }, { "name": "Food", "trend": "stable", "trendPct": 2.1 }, { "name": "Housing", "trend": "stable", "trendPct": 0 }, { "name": "Software", "trend": "down", "trendPct": 6.8 } ] } ``` ### Response fields | Field | Type | Description | | --- | --- | --- | | `months[]` | array | Monthly totals in chronological order. | | `.period` | string | Month (`YYYY-MM`). | | `.total` | integer | Total amount in cents. | | `avgMonthly` | integer | Average monthly amount in cents. | | `trend` | string | `"up"` (>5%), `"down"` (<−5%), or `"stable"`. | | `trendPct` | number | Absolute trend percentage (1 decimal). Calculated via linear regression. | | `categoryTrends[]` | array | Per-category trends, sorted by trendPct descending. | | `.name` | string | Category name. | | `.trend` | string | `"up"`, `"down"`, or `"stable"`. | | `.trendPct` | number | Absolute trend percentage (1 decimal). | **Trend calculation** Trend direction is determined by linear regression across all months. The percentage represents the total change from first to last month relative to the first month's value. Thresholds: `> 5%` = up, `< −5%` = down, otherwise stable. ## Anomalies `GET /api/v1/insights/anomalies` · Permission: `expenses.read` Detects unusually large expenses using two methods: (1) comparison against 6-month historical average per category, (2) median-based intra-period outlier detection. ### Query parameters | Param | Type | Required | Description | | --- | --- | --- | --- | | `period` | string | Yes | Month in `YYYY-MM` format. | | `threshold` | number | No | Multiplier threshold (1–10). Default: `2.0`. Expense flagged when amount ≥ threshold × average. | ### Example requests ``` # Default threshold (2x) curl -X GET "https://api.figa.cc/api/v1/insights/anomalies?period=2026-02" \ -H "x-api-key: et_live_abc123..." # Stricter threshold (3x) curl -X GET "https://api.figa.cc/api/v1/insights/anomalies?period=2026-02&threshold=3" \ -H "x-api-key: et_live_abc123..." ``` ### Response ``` { "period": "2026-02", "anomalies": [ { "expense": { "id": "Emergency server-1740009600000", "name": "Emergency server", "amount": 450000 }, "reason": "4.7x średnia dla kategorii Cloud", "avgForCategory": 95744 }, { "expense": { "id": "Team offsite-1740268800000", "name": "Team offsite", "amount": 280000 }, "reason": "3.1x mediana wydatków w okresie", "avgForCategory": 90000 } ] } ``` ### Response fields | Field | Type | Description | | --- | --- | --- | | `period` | string | Requested period. | | `anomalies[]` | array | Detected anomalies, sorted by ratio (highest first). Empty array if none found. | | `.expense.id` | string | Generated identifier. | | `.expense.name` | string | Expense name. | | `.expense.amount` | integer | Amount in cents. | | `.reason` | string | Human-readable explanation, e.g. `"4.7x średnia dla kategorii Cloud"` or `"3.1x mediana wydatków w okresie"`. | | `.avgForCategory` | integer | The reference average or median used for comparison (cents). | ### Detection methods | Method | Logic | reason prefix | | --- | --- | --- | | Historical | Compares each expense against the 6-month average for its category. | `Nx średnia dla kategorii X` | | Intra-period | Uses median of all expenses in the period. Catches outliers without history. | `Nx mediana wydatków w okresie` | ## Forecast This endpoint projects total spending. For individual variable bill amounts, methods and reliability, see [bill forecasts](https://getfiga.com/help/developers/api#bill-forecasts). `GET /api/v1/insights/forecast` · Permission: `expenses.read` Linear projection of current spending to full month, plus scheduled recurring expenses that haven't been paid yet. ### Query parameters | Param | Type | Required | Description | | --- | --- | --- | --- | | `period` | string | Yes | Month in `YYYY-MM` format. | ### Example request ``` curl -X GET "https://api.figa.cc/api/v1/insights/forecast?period=2026-02" \ -H "x-api-key: et_live_abc123..." ``` ### Response ``` { "period": "2026-02", "currentTotal": 520000, "daysElapsed": 16, "daysRemaining": 12, "projectedTotal": 910000, "upcomingRecurring": [ { "name": "Netflix", "amount": 4999, "dueDate": "2026-02-20" }, { "name": "Office rent", "amount": 420000, "dueDate": "2026-03-01" } ], "projectedWithRecurring": 1334999 } ``` ### Response fields | Field | Type | Description | | --- | --- | --- | | `period` | string | Requested period. | | `currentTotal` | integer | Amount spent so far (cents). | | `daysElapsed` | integer | Days passed in the period. | | `daysRemaining` | integer | Days left in the period. | | `projectedTotal` | integer | Linear projection: `(currentTotal / daysElapsed) × daysInMonth`. | | `upcomingRecurring[]` | array | Unpaid recurring expenses still due this month, sorted by date. | | `.name` | string | Recurring expense name. | | `.amount` | integer | Amount in cents. | | `.dueDate` | string | Due date (`YYYY-MM-DD`). | | `projectedWithRecurring` | integer | `projectedTotal + sum(upcomingRecurring.amount)`. | **Projection logic** For the **current month**, `daysElapsed` is today's date and `upcomingRecurring` only includes items scheduled after today. For **past months**, the full month is used and there are no upcoming items. For **future months**, `currentTotal` is 0 and all recurring items are listed. ## Integration examples ### Monthly Slack report (Make / n8n) Fetch summary at end of month and post to Slack. ``` # 1. Fetch summary for current month curl -X GET "https://api.figa.cc/api/v1/insights/summary?period=2026-02" \ -H "x-api-key: et_live_abc123..." # 2. Fetch comparison with previous month curl -X GET "https://api.figa.cc/api/v1/insights/comparison?p1=2026-02&p2=2026-01" \ -H "x-api-key: et_live_abc123..." # 3. Format and send to Slack webhook ``` ### Spending anomaly alert Run daily/weekly to catch unusual expenses early. ``` # Flag expenses exceeding 3x category average curl -X GET "https://api.figa.cc/api/v1/insights/anomalies?period=2026-02&threshold=3" \ -H "x-api-key: et_live_abc123..." # If anomalies[] is non-empty → send alert ``` ### Budget projection dashboard Combine forecast with trends for a dashboard widget. ``` # Current month projection curl -X GET "https://api.figa.cc/api/v1/insights/forecast?period=2026-02" \ -H "x-api-key: et_live_abc123..." # 12-month trend for chart curl -X GET "https://api.figa.cc/api/v1/insights/trends?months=12" \ -H "x-api-key: et_live_abc123..." ``` --- Source: https://getfiga.com/help/developers/agent-skills/ # Agent skills for Figa Give your agent a connection and a repeatable way to use it. This pack contains standard `SKILL.md` instructions, supporting references and optional Python helpers. It works independently of a particular chat product; installation and tool access depend on your runtime. [Download Figa agent skills (.zip)](https://getfiga.com/help/downloads/figa-agent-skills.zip) ## Five workflows - `figa-api-read`: read context, expenses and summaries through MCP or REST. The existing name is retained for compatibility. - `figa-expense-write`: create and update expenses with explicit recurring scope and retry rules. - `figa-organize-expenses`: manage local categories and tags, preserving the intended assignments. - `figa-recurring-bills`: confirm invoices, explain forecasts and change monthly billing settings with the intended scope. - `figa-integration-playbooks`: build an event-driven or scheduled workflow with verification and source deduplication. ## Install and connect 1. Extract the ZIP and read its README. Copy the individual `figa-*` folders into your agent’s skill directory. Each installed folder must directly contain `SKILL.md`; the ZIP’s outer folder is not itself a skill. 2. Use your runtime’s documented loader. OpenClaw uses workspace or shared skill directories; see the [OpenClaw guide](https://getfiga.com/help/developers/integrations/openclaw). For Hermes, dots, Grok bots, Muse or another agent, check its supported skill and tool formats. 3. If there is no skill loader, provide the relevant instructions and references as task context. Configure a working tool connection separately; instructions cannot add capabilities to a client. 4. [Connect MCP with OAuth](https://getfiga.com/help/developers/mcp), or configure REST with `FIGA_API_BASE_URL=https://api.figa.cc` and `FIGA_API_KEY` in the runtime’s secret store. Only the optional REST helpers need Python 3.10+. 5. Start with one read: “Show this month’s expenses in my Home workspace, separating confirmed amounts and estimates.” Verify the selected workspace and dates. Agents vary in support for remote MCP, OAuth, skill loading and interactive MCP Apps views. The pack does not imply a native integration or verified support for every named client. The connected server’s current schemas and your granted permissions determine what is available. ## Try a practical task > Use this invoice to update the matching recurring electricity bill. Show me the match and proposed amount before saving, then list the bills still unpaid this month. The [invoice walkthrough](https://getfiga.com/help/developers/invoice-workflow) explains the matching, confirmation and follow-up analysis. Your external tool reads the document; Figa stores the expense and bill data. For forecasting, try: “Use seasonal forecasts for my gas bills and explain the December estimate.” The [forecast guide](https://getfiga.com/help/bill-forecasts) covers the four methods, missing history and reliability. The skills distinguish recurring scopes, full tag-set replacement, confirmed amounts and estimates, and binary payment status. Reuse operation IDs for retries and keep a source ledger for recurring automation. Existing installations can still use the [OpenClaw download link](https://getfiga.com/help/developers/openclaw-skills). Both downloads are built from the same maintained sources. --- Source: https://getfiga.com/help/developers/openclaw-skills/ # OpenClaw skills are now Figa agent skills The pack now covers MCP and REST, recurring invoices, categories and tags. The original download address remains available and uses the same sources as the general agent pack. [Download the compatible OpenClaw pack (.zip)](https://getfiga.com/help/downloads/figa-openclaw-skills.zip) [See all skills and connection options](https://getfiga.com/help/developers/agent-skills), or follow the [OpenClaw installation guide](https://getfiga.com/help/developers/integrations/openclaw). Extract the archive first, then copy its individual `figa-*` directories into your skill directory. Each skill’s `SKILL.md` must sit directly inside its installed folder. --- Source: https://getfiga.com/help/developers/presets/ # Integration recipes Use these patterns in your agent or automation runner. They are implementation guides, not a built-in catalog of one-click connectors. - [Recurring invoice](https://getfiga.com/help/developers/invoice-workflow): extract fields externally, match an existing bill, confirm its amount and analyze the updated records. - [Monthly reconciliation](https://getfiga.com/help/developers/api-insights): compare explicit periods and currencies, keeping estimates and unknowns visible. - [Expense organization](https://getfiga.com/help/developers/agent-skills): create local categories, rename tags and update assignments with an explicit recurring scope. For each recipe, read context first, use stable operation IDs for retries, verify the saved result and keep a durable source-event ledger. Choose [MCP](https://getfiga.com/help/developers/mcp) for a compatible agent or the [REST API](https://getfiga.com/help/developers/api) for HTTP workflows. --- Source: https://getfiga.com/help/developers/integrations/raycast/ # Raycast Extension The Figa Raycast extension gives you quick desktop access to workspace context, expenses, monthly totals, categories, recipients, expense creation, and selected-expense payment actions. **Current plan limits apply** Free includes one shared API key or MCP workspace connection slot per organization. After downgrade, the oldest eligible integration remains active and excess keys are suspended. Free exposes the oldest 20 expenses per month across the organization; Pro restores access to retained expenses and eligible keys. ## Setup 1. Open Figa workspace settings and create a dedicated API key for Raycast. 2. Choose the read preset for lookup-only commands or the write preset for create and payment workflows. 3. Copy the key immediately. Figa shows the raw API key only once. 4. Install or run the Figa Raycast extension and open extension preferences. 5. Paste the key into API Key. 6. Run Show Workspace Context first to verify workspace, plan, defaults, and capabilities. **API key safety** API keys are shown once. Create a key dedicated to Raycast, store it only in Raycast preferences, and rotate it from Figa workspace settings if it was pasted into logs, screenshots, chat, or another tool. ## Preferences | Preference | Value | Notes | | --- | --- | --- | | `API Key` | Password field | Use a workspace API key. Raycast stores it as an extension password preference. | ## Capabilities Every command starts from `GET /api/v1/context`. Context v2 includes workspace defaults and capability flags derived from the configured key. Raycast uses those flags to show clear permission states before mutation requests are sent. - `defaults.baseCurrency` pre-fills create-expense currency. - `expenses.read` gates expense search and monthly totals. - `categories.read` and `recipients.read` gate reference commands and create-form choices. - `expenses.write` gates expense creation. - `expenses.payments` gates selected-expense mark-paid actions. Legacy write keys may still be accepted by the API payment route. ## Commands | Command | Capability | Expected behavior | | --- | --- | --- | | Show Workspace Context | `workspaces.read` | Shows workspace, plan, critical limits, defaults, capabilities, and key settings links. | | Search Expenses | `expenses.read` | Shows current-month expenses with all, unpaid, and paid views plus copy, paste, and Figa links. | | Show Monthly Summary | `expenses.read` | Shows recent total, paid, and unpaid monthly values using workspace currency. | | Search Categories / Search Recipients | `categories.read`, `recipients.read` | Shows live workspace/global reference data with expense counts and Figa links. | | Create Expense | `expenses.write` | Uses workspace defaults and live references, validates form fields, and sends an idempotent create request. | | Mark Expense Paid | `expenses.payments` | Reads the expense, asks for confirmation, sets Paid with its context and revisions, then reads current status and refreshes the list. | --- Source: https://getfiga.com/help/developers/integrations/n8n/ # n8n Integration Use n8n when you need custom orchestration and branch logic between internal tools and Figa. 1. Create an API key in Workspace settings → API & MCP (owner/admin only). 2. In n8n, define credential as HTTP Header Auth: x-api-key = et\_... 3. Add HTTP Request node to GET /api/v1/categories and verify connectivity. 4. Read context, match the source event to an existing record, then create or update the intended expense. 5. Reuse the operation UUID on supported retries. Inspect 403/409 codes; wait on Retry-After for 429, and resolve uncertain writes before a new operation. Use `https://api.figa.cc` as the API origin. Configure UUID `Idempotency-Key` for POST mutations and supported bill PUTs; keep a durable source-event ledger. API keys share integration slots with MCP connections. For monthly invoices, [match and confirm the existing recurring bill](https://getfiga.com/help/developers/invoice-workflow). PDF extraction and the event trigger belong to your n8n workflow. Use the create below only for a genuinely new record. ## Minimal create payload ``` { "name": "Invoice #481", "amount": 129900, "categoryInput": "Software", "recipientInput": "Acme Corp", "expenseDate": 1739577600 } ``` **Choose access and approval** Start with a read request. Configure review for ambiguous matches before unattended writes. Saving an amount alone preserves status; marking Paid does not transfer money. --- Source: https://getfiga.com/help/developers/integrations/zapier/ # Zapier Integration Use Webhooks by Zapier for an HTTP workflow with the Figa REST API. API keys share the plan’s integration slots with MCP connections. 1. Generate API key in Figa workspace settings. 2. Create Zap trigger (for example: new invoice in your source app). 3. Read context and match the invoice first. For a new record, POST to https://api.figa.cc/api/v1/expenses. 4. Pass x-api-key and a saved UUID Idempotency-Key for this create; map amount as integer minor units and include currency. 5. Test and publish Zap with error handling branch. For an existing recurring bill, follow the [invoice matching and confirmation recipe](https://getfiga.com/help/developers/invoice-workflow) instead of creating a duplicate. Keep a durable source-event ledger beyond the 24-hour retry window. Only mark Paid when the source confirms the expense was paid. ## Headers for a new expense ``` x-api-key: et_... Content-Type: application/json Idempotency-Key: ``` **Common mistake** Do not send decimal amounts (for example 142.50). API expects integer cents (for example 14250). --- Source: https://getfiga.com/help/developers/integrations/openclaw/ # OpenClaw integration Use the shared [Figa agent skills](https://getfiga.com/help/developers/agent-skills) for expense questions, category and tag changes, and recurring invoice workflows. They describe the same Figa operations used by other agents. ## Install the skill folders 1. Download and extract [figa-agent-skills.zip](https://getfiga.com/help/downloads/figa-agent-skills.zip). 2. Copy the individual skill folders from inside the bundle to `/skills/` or `~/.openclaw/skills/`. Do not leave them nested inside the bundle wrapper. 3. Reload skills or start a new session. Review the instructions and optional scripts before enabling writes. ``` unzip figa-agent-skills.zip mkdir -p ./skills cp -R figa-agent-skills/figa-* ./skills/ ``` ## Choose the tool connection If your OpenClaw setup supports remote MCP with OAuth, add `https://api.figa.cc/mcp` and follow the [MCP connection guide](https://getfiga.com/help/developers/mcp). Otherwise configure HTTP tools for `https://api.figa.cc/api/v1` with the `x-api-key` header. MCP uses OAuth, not the API key. For the optional Python helpers, store `FIGA_API_BASE_URL=https://api.figa.cc` and `FIGA_API_KEY` in your runtime’s secrets. Resolve script paths relative to each installed skill. The helpers read basic resources or create an expense; other operations use the live MCP tools or documented REST endpoints. ## First run Read context, list one month and check the workspace and currency. Then try an explicitly requested change and read it back. Configure the agent’s approval policy before unattended writes. Payment recording updates Figa’s record and does not transfer money. For a repeatable daily task, follow [an invoice into its existing recurring bill](https://getfiga.com/help/developers/invoice-workflow), then use the saved data for summaries and comparisons. See the [OpenClaw skills documentation](https://docs.openclaw.ai/skills) for current locations and loading behavior.