Back to the help center
Integrations

Public API: connect your software to Norman

Create an API key, understand company access and permissions, and make your first request from a script or integration.

Updated

What can I build with the API?

The Public API lets software read or change supported Norman records through HTTP requests. Use it to copy transactions into a dashboard, maintain clients from a CRM, prepare invoice drafts or upload supporting documents.

The public reference covers company details, transactions, existing bank connections, clients, the product and service catalog, invoices, recurring schedules, documents and tax report/settings reads. It also includes document recognition, PDF/XML retrieval and invoice-to-payment matching. Available actions differ by resource. Payments, bank authorization and tax filing are not operations in this Public API contract.

Use the developer documentation for the exact operations, fields and examples. If you need the OpenAPI JSON file for your integration, contact support.

Choose your workflow

  • Documents and OCR: upload a receipt, read extracted fields, re-run recognition or submit an image crop. Import already processed documents without OCR using an external source and ID for retries.
  • Batch processing: upload up to 20 documents, with a maximum of 10 MB per file and 50 MB total, then poll the job for progress, created transactions and per-file errors. This workflow can create or match transactions, so uploading requires both write_documents and write_transactions; reading progress requires both read permissions. A completed job can include failed files.
  • Supporting documents: attach a delivery note or other extra file to a transaction without OCR or replacing its primary receipt. Correcting document metadata can update linked transactions and requires both write permissions.
  • Invoicing: sync products and services, get the next invoice-number suggestion, retrieve PDF/XML, match invoice payments and send eligible overdue reminders. Read an existing recurring schedule or stop the series. Product catalog operations use invoice permissions.
  • Contract proposals: read invoice terms from a contract, then review the recipient, amounts, dates and notes before creating an invoice. Proposal line rates use major currency units; invoice creation uses minor units. The proposal does not itself create or send an invoice.

Follow the complete examples for documents and OCR or invoicing workflows. Each operation in the reference lists its required permissions.

Create a key

  1. Open Automations → Integrations → Public API, or go to the key controls.
  2. Select the company whose records your integration needs. Copy its company ID if your requests will need it.
  3. Create a named key, choose its permissions and set an expiry. Start with Read only for reporting. The Invoicing preset includes client and invoice reads and writes.
  4. Copy the key when it appears. The full value is shown once; the list retains its prefix and status.
  5. Store it in your server's environment or your automation tool's credential store. Do not put it in a public website, repository, screenshot or shared workflow export.

One key, one company

Send Authorization: Bearer YOUR_API_KEY with the request. The key is bound to its company. Company IDs in paths, bodies or an optional X-Company-Id header must match it. Client and document references must also belong to that company.

Read and write permissions are separate. For example, read_transactions reads transactions, while write_invoices allows supported invoice writes and does not automatically grant invoice reads. full_access covers the public operations for the key's company. Account permissions, plan requirements and document state still apply.

Make a first request

This example reads the company associated with the key. Replace the placeholder locally:

export NORMAN_API_KEY='nrm_replace_with_your_key'

curl --fail-with-body 'https://api.norman.finance/api/v1/companies/' \
  -H "Authorization: Bearer $NORMAN_API_KEY"

A successful response has HTTP status 200 and a results list. Save the company's publicId for paths that need a company ID. Archived companies are hidden from the list by default; use ?include_archived=true if needed.

With read_transactions, you can then read a first page of transactions:

curl --fail-with-body 'https://api.norman.finance/api/v1/accounting/transactions/?page=1&page_size=20' \
  -H "Authorization: Bearer $NORMAN_API_KEY"

List responses include results, next, previous and count. Follow next until it is null for a complete export. An empty transaction list can be a successful response.

Build the next step

The recipes show client creation, invoice drafts, document uploads and paginated reporting. JSON fields use camelCase; query names such as page_size use the spelling shown in the reference. Transaction amounts and invoice line rates use minor currency units: 4999 is €49.99 for EUR. Read the request schema before copying values from a response back into a write.

Rotate keys and resolve errors

Create a replacement key, update the integration, verify one request, then revoke the old key. Expired or revoked keys stop working; access also depends on the creator's current account and company access.

  • 401: check the Bearer header and whether the key expired or was revoked.
  • 403: check permissions, company, supported operation and account requirements.
  • 400 or 422: correct the field values or document state using the response details.
  • 429: wait for Retry-After before retrying.

Before repeating a timed-out write, check whether the record was already created. See errors and retries for more detail.

For a visual integration, continue with n8n or Make. For an AI assistant, use the MCP connection guide.

Norman handles the operational finance work

Invoicing, receipts, bookkeeping, and taxes in one workflow: start for free.