---
title: "Connect Fortnox to AI Agents: Automate Billing and ERP Tasks"
slug: connect-fortnox-to-ai-agents-automate-billing-and-erp-tasks
date: 2026-09-16
author: Yuvraj Muley
categories: ["AI & Agents"]
excerpt: "A complete engineering guide to connecting Fortnox to AI agents. Learn how to fetch AI-ready tools, handle financial API quirks, and build autonomous workflows."
tldr: "Connect Fortnox to your AI agents using Truto's unified tool layer. This guide covers API quirks, tool schemas, rate limiting, and building multi-step ERP workflows in LangChain."
canonical: https://truto.one/blog/connect-fortnox-to-ai-agents-automate-billing-and-erp-tasks/
---

# Connect Fortnox to AI Agents: Automate Billing and ERP Tasks


You want to connect Fortnox to an AI agent so your system can autonomously onboard customers, track suppliers, generate invoices, and manage inventory based on historical context. Here is exactly how to do it using Truto's `/tools` endpoint and SDK, bypassing the need to [build and maintain a custom Fortnox connector](https://truto.one/how-to-build-an-ai-agent-to-erp-integration-a-code-first-tutorial/) from scratch.

Giving a Large Language Model (LLM) read and write access to your ERP and accounting software is an engineering challenge with zero margin for error. You either spend weeks building, hosting, and maintaining a custom connector that deals with Fortnox's strict relational data models, or you use a managed infrastructure layer that handles the boilerplate. If your team uses ChatGPT, check out our guide on [connecting Fortnox to ChatGPT](https://truto.one/connect-fortnox-to-chatgpt-manage-invoicing-and-customer-data/), or if you are building on Anthropic's models, read our guide on [connecting Fortnox to Claude](https://truto.one/connect-fortnox-to-claude-track-suppliers-sales-and-inventory/). For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them to your agent framework.

This guide breaks down exactly how to fetch AI-ready tools for Fortnox, bind them natively to an LLM using LangChain (or any framework like LangGraph, CrewAI, or Vercel AI SDK), and execute complex ERP operations safely. For a deeper look at the architecture behind this approach, refer to our research on [architecting AI agents and the SaaS integration bottleneck](https://truto.one/architecting-ai-agents-langgraph-langchain-and-the-saas-integration-bottleneck/).

## The Engineering Reality of the Fortnox API

Giving an LLM access to external accounting data sounds simple in a prototype. You write a Node.js function that makes a fetch request and wrap it in an `@tool` decorator. In production against [complex ERP systems](https://truto.one/connect-ai-agents-to-netsuite-sap-via-mcp-the-2026-architecture-guide/), this approach collapses.

Fortnox's API introduces several specific integration challenges that break standard REST assumptions. If you hardcode these interactions into your agent, you will spend your sprints writing defensive integration code instead of improving your model's reasoning.

### Strict Financial State Transitions

Standard LLMs are trained to expect that CRUD (Create, Read, Update, Delete) applies universally. Fortnox enforces strict accounting principles. You cannot simply `DELETE` an invoice once it has been booked. Invoices have strict states (`DRAFT`, `BOOKED`, `CANCELLED`). If an agent attempts to update a booked invoice with standard REST logic, the API will reject it. Your agent must understand that reversing a transaction often requires creating a credit note or explicitly annulling the record, rather than issuing a standard HTTP DELETE request. 

### Relational Entity Dependencies

Fortnox relies heavily on composite lookups. To create an invoice, you cannot just pass a customer's name or a generic string ID. You must provide a specific `CustomerNumber` and `ArticleNumber`. This means an agent cannot simply infer an invoice payload from a user prompt. It must first execute a search query to resolve the customer, then execute a search query to resolve the catalog article, and only then construct the nested `InvoiceRows` array. Exposing raw OpenAPI specs to an LLM usually results in hallucinations because the model forgets to chain these dependent lookups in the correct order.

### Brutal Rate Limiting Rules

Fortnox enforces strict API rate limits per access token to protect their infrastructure. When you hit these limits, Fortnox rejects requests. This is where many custom integrations fail. 

Truto does not magically absorb or retry rate limit errors. When Fortnox returns an HTTP 429, Truto passes that error directly to the caller. However, Truto normalizes the upstream rate limit information into standardized IETF headers (`ratelimit-limit`, `ratelimit-remaining`, `ratelimit-reset`). This is critical for AI agents: instead of forcing the agent to parse undocumented JSON error bodies to guess when it can try again, your agent framework can intercept the standardized 429 response, read the `ratelimit-reset` header, and deterministically backoff before resuming its tool execution loop.

## Why a Unified Tool Layer Matters for Agent Safety

Before writing a line of integration code, decide what layer your agent talks to. Direct API tools (one tool per raw Fortnox endpoint) look convenient but they push provider quirks into the LLM's context. The model has to remember exactly how Fortnox formats organization numbers, how it handles pagination cursors, and the exact naming conventions of its deeply nested JSON structures.

[Truto's unified tool layer](https://truto.one/best-unified-api-for-llm-function-calling-ai-agent-tools-2026/) collapses these complexities. Your agent sees simple, descriptive function names with strict JSON schemas. 

1. **Smaller attack surface for hallucination.** The LLM only ever chooses from stable function names like `create_a_fortnox_invoice`. It never invents raw HTTP paths or query string parameters.
2. **Deterministic input validation.** Every tool has a strict JSON schema. Invalid arguments are rejected before they hit Fortnox, so a broken tool call fails fast instead of creating corrupt financial records.
3. **Framework agnostic.** The `/tools` endpoint returns definitions that easily map into `.bindTools()` for LangChain, OpenAI function schemas, or Anthropic tool definitions.

## Hero Tools for Fortnox AI Agents

Truto provides a comprehensive suite of Proxy APIs for Fortnox. When you call the `/tools` endpoint, these methods are translated into highly described JSON schemas optimized for LLM consumption. Here are the highest-leverage tools for automating ERP workflows.

### 1. list_all_fortnox_customers

Before an agent can generate a quote, order, or invoice, it must resolve the target entity. This tool retrieves a paginated list of customers, sorted by customer number. It allows the agent to filter by email, name, or phone number to find exact matches.

**Contextual usage notes:** Agents should be instructed to always use this tool to search for a customer by email or name before attempting to create a new one, preventing duplicate records in the ERP.

> "Search our Fortnox system to see if we have an active customer record for 'Acme Corp' or the email 'billing@acmecorp.com'."

### 2. create_a_fortnox_customer

If a customer does not exist, the agent can use this tool to onboard them. It accepts standard customer details and strictly enforces Fortnox's requirement for a valid `Name`.

**Contextual usage notes:** The tool returns the newly generated `CustomerNumber`, which the agent must extract and keep in context for subsequent invoicing tools.

> "Create a new active customer record for 'Tech Innovations Inc.' with the organization number 555-1234 and return their new customer number."

### 3. list_all_fortnox_articles

Invoices in Fortnox require specific line items tied to the company's article catalog. This tool allows the agent to search the catalog and retrieve exact `ArticleNumber` values.

**Contextual usage notes:** Because LLMs are prone to hallucinating line-item prices, forcing the agent to fetch the source of truth from the article list ensures the invoice generated matches the agreed-upon catalog pricing.

> "Find the article number and current price for our 'Enterprise Consulting Retainer' service in the Fortnox catalog."

### 4. create_a_fortnox_invoice

This is the core monetization tool. It generates an invoice for a customer by accepting a `customer_number`, an `invoice_date`, and a nested array of `invoice_rows`.

**Contextual usage notes:** Instruct your agent to construct the `invoice_rows` array precisely, ensuring each row maps to a valid article number retrieved in a previous step.

> "Generate an invoice for customer number 1042 for today's date, adding one row for article number 50 (Consulting) and two rows for article number 12 (Software License)."

### 5. get_single_fortnox_invoice_by_id

This tool retrieves the full state of a specific invoice. It is heavily utilized in customer support workflows to answer inquiries about billing.

**Contextual usage notes:** Useful for verifying the status of an invoice (e.g., checking if it is booked, cancelled, or paid) before attempting to send reminders or issue credits.

> "Check the status and total balance of Fortnox invoice number 40992 and tell me if it has been booked."

### 6. list_all_fortnox_suppliers

For accounts payable (AP) automation, agents need to interact with the vendor side of the ledger. This tool lists all suppliers, allowing agents to audit active vendors, retrieve VAT numbers, and verify contact information.

**Contextual usage notes:** Ideal for vendor risk management workflows or routing AP inquiries to the correct department based on the supplier's active status.

> "Retrieve a list of all active suppliers in Fortnox and find the VAT number for 'Office Supplies Direct'."

To view the complete inventory of available proxy tools, schemas, and resource definitions, visit the [Fortnox integration page](https://truto.one/integrations/detail/fortnox).

## Workflows in Action

Standalone tools are useful, but the real power of an AI agent lies in chaining these tools together to execute complex, multi-step workflows. Here is how specific personas use these tools in production.

### Scenario 1: Autonomous Quote-to-Cash (Sales Operations)

A sales operations manager needs to convert a won deal in a CRM into a finalized invoice in Fortnox without manual data entry.

> "We just closed a deal with 'Globex Corporation'. Ensure they exist as a customer in Fortnox, find the article code for 'Annual SaaS License', and generate a new invoice for one license."

**Step-by-step Execution:**
1. The agent calls `list_all_fortnox_customers` filtering for the name "Globex Corporation".
2. The ERP returns empty. The agent dynamically pivots and calls `create_a_fortnox_customer` using the details provided in its context, receiving `CustomerNumber: 8841` in return.
3. The agent calls `list_all_fortnox_articles` to search for "Annual SaaS License" and extracts `ArticleNumber: 101`.
4. The agent calls `create_a_fortnox_invoice` passing `CustomerNumber: 8841` and an `invoice_rows` array containing `ArticleNumber: 101`.

**The Result:** The user receives a confirmation that a new customer was onboarded and Invoice #4502 was successfully generated, entirely autonomously.

### Scenario 2: Vendor Compliance Audit (Procurement)

A procurement officer needs to verify supplier tax details against internal compliance requirements.

> "Audit our Fortnox system for the supplier 'Logistics Partners LLC' and return their full address and VAT number for my compliance report."

**Step-by-step Execution:**
1. The agent calls `list_all_fortnox_suppliers` to find the exact match for "Logistics Partners LLC" and retrieves their internal `SupplierNumber`.
2. The agent calls `get_single_fortnox_supplier_by_id` passing the extracted ID to pull the full vendor object.
3. The agent parses the response, extracting the `City`, `CountryCode`, and `VATNumber`.

**The Result:** The user receives a formatted compliance summary containing exactly the requested vendor data, isolated from the noise of the raw API response.

## Building Multi-Step Workflows

To implement these workflows in code, you need an orchestration layer. While Truto's `/tools` endpoint serves standard JSON, developers using JavaScript or TypeScript can use the [Langchain.js SDK](https://github.com/trutohq/truto-langchainjs-toolset) to automatically bind these tools to an agent.

Here is how you orchestrate a multi-step Fortnox workflow using LangGraph, specifically addressing how to handle the inevitable rate limits.

### Handling Rate Limits with Truto and AI Agents

When scaling agentic workflows, LLMs execute tools rapidly. Fortnox enforces strict rate limits. When a limit is breached, Fortnox returns a 429. Truto normalizes this upstream error into standardized IETF headers.

Your agent execution loop must catch HTTP 429 errors, inspect the `ratelimit-reset` header provided by Truto, sleep for the required duration, and then allow the agent to retry the tool call. **Truto does not absorb or retry these for you; your code must handle the backoff.**

```mermaid
sequenceDiagram
    participant User as User Prompt
    participant Agent as LangGraph Agent
    participant Truto as Truto Unified API
    participant Fortnox as Fortnox Upstream API

    User->>Agent: "Invoice Acme Corp..."
    Agent->>Truto: Call tool list_all_fortnox_customers
    Truto->>Fortnox: GET /3/customers
    Fortnox-->>Truto: 200 OK
    Truto-->>Agent: CustomerNumber: 1045
    Note over Agent: Planning next step...
    Agent->>Truto: Call tool get_single_fortnox_article_by_id
    Truto->>Fortnox: GET /3/articles
    Fortnox-->>Truto: 429 Too Many Requests
    Truto-->>Agent: 429 (ratelimit-reset: 10)
    Note over Agent: Caller catches 429, sleeps 10s
    Agent->>Truto: Retry tool get_single_fortnox_article_by_id
    Truto->>Fortnox: GET /3/articles
    Fortnox-->>Truto: 200 OK
    Truto-->>Agent: Article details returned
```

### The Implementation Code

Below is a conceptual TypeScript example using `@langchain/core` demonstrating how to fetch Truto tools, bind them to an OpenAI model, and wrap the execution in a resilient loop that respects Truto's normalized rate limit headers.

```typescript
import { ChatOpenAI } from "@langchain/openai";
import { TrutoToolManager } from "truto-langchainjs-toolset";

// 1. Initialize the Truto Tool Manager with your Integrated Account ID
// This automatically fetches all Fortnox Proxy Methods as LLM tools
const toolManager = new TrutoToolManager({
  trutoApiKey: process.env.TRUTO_API_KEY,
  integratedAccountId: "your_fortnox_account_id"
});

// 2. Fetch tools and bind them to the LLM
const tools = await toolManager.getTools();
const llm = new ChatOpenAI({ modelName: "gpt-4o", temperature: 0 });
const llmWithTools = llm.bindTools(tools);

// 3. Define a resilient execution loop
async function executeAgentWithBackoff(prompt: string) {
  let messages = [{ role: "user", content: prompt }];
  
  while (true) {
    const response = await llmWithTools.invoke(messages);
    messages.push(response);
    
    // If the LLM decides it has finished planning and needs no more tools
    if (!response.tool_calls || response.tool_calls.length === 0) {
      return response.content;
    }

    // Execute tools requested by the LLM
    for (const toolCall of response.tool_calls) {
      try {
        // Find and execute the requested Fortnox tool
        const tool = tools.find(t => t.name === toolCall.name);
        const toolResult = await tool.invoke(toolCall.args);
        
        messages.push({ 
          role: "tool", 
          tool_call_id: toolCall.id, 
          content: JSON.stringify(toolResult) 
        });
        
      } catch (error: any) {
        // 4. Handle Truto's standardized rate limit headers
        if (error.status === 429) {
          // Extract the IETF standard header passed through by Truto
          const resetAfterSeconds = parseInt(error.headers['ratelimit-reset'] || '5', 10);
          console.log(`Rate limit hit. Agent sleeping for ${resetAfterSeconds} seconds.`);
          
          await new Promise(resolve => setTimeout(resolve, resetAfterSeconds * 1000));
          
          // Instruct the agent to retry the specific tool call
          messages.push({
            role: "tool",
            tool_call_id: toolCall.id,
            content: "Error 429: Rate limit exceeded. Please try this exact tool call again."
          });
        } else {
          // Feed standard API errors (e.g., validation failures) back to the LLM
          messages.push({
            role: "tool",
            tool_call_id: toolCall.id,
            content: `Execution failed: ${error.message}`
          });
        }
      }
    }
  }
}

// Run the workflow
const result = await executeAgentWithBackoff(
  "Search for customer 'Globex' and generate an invoice for Article 101."
);
console.log("Agent finished:", result);
```

By flattening Fortnox's strict relational requirements into semantic tools and standardizing upstream rate limits via IETF headers, Truto removes the infrastructure burden of ERP integrations. Your agent can navigate financial lookups securely, backoff gracefully when Fortnox requests it, and execute complex billing workflows without custom pipeline code.

:::cta{buttonText="Talk to us" buttonUrl="/book-a-demo/"} 
Ready to connect your AI agents to Fortnox and 100+ other SaaS applications? Book a demo with our engineering team to see Truto's unified tool layer in action.
:::
