Skip to main content

REST-API

Frihet REST-API lar deg programmatisk få tilgang til og manipulere kontoens ressurser. All kommunikasjon foregår over HTTPS og svarene er JSON.

Base-URL

https://api.frihet.io/v1

Alle endepunktene beskrevet på denne siden er relative til denne base-URL-en.

Oppdagelse: En GET-forespørsel til roten (https://api.frihet.io/) returnerer hovedlenkene uten behov for autentisering:

{
"name": "Frihet API",
"version": "1.0.0",
"docs": "https://docs.frihet.io/desarrolladores/api-rest",
"openapi": "https://api.frihet.io/openapi.yaml",
"mcp": "https://mcp.frihet.io",
"status": "https://status.frihet.io"
}

OpenAPI 3.1-spesifikasjonen er tilgjengelig på https://api.frihet.io/openapi.yaml.

SDK tilgjengelig

Hvis du bruker TypeScript eller JavaScript, forenkler den offisielle SDK-en integrasjonen:

npm install @frihet/sdk
import Frihet from '@frihet/sdk';
const frihet = new Frihet({ apiKey: 'fri_...' });
const invoices = await frihet.invoices.list({ status: 'overdue' });

Repository: github.com/Frihet-io/frihet-sdk


Autentisering

Hver forespørsel må inkludere en API-nøkkel i X-API-Key-headeren. Nøkler opprettes fra Innstillinger > Utviklere > API-nøkler i Frihet-panelet.

Nøklene har prefikset fri_ etterfulgt av 32 tilfeldige bytes kodet i base64url. Eksempel: fri_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345678.

curl https://api.frihet.io/v1/clients \
-H "X-API-Key: fri_tu-clave-aqui"

Alternativt kan du sende nøkkelen som en Bearer-token i Authorization-headeren:

curl https://api.frihet.io/v1/clients \
-H "Authorization: Bearer fri_tu-clave-aqui"

Nøkkel-sikkerhet

  • Nøkkelen i klartekst vises kun én gang, ved opprettelsen. Den kan ikke gjenopprettes etterpå.
  • Serveren lagrer en SHA-256 hash av nøkkelen. Selv i tilfelle datainnbrudd er den originale nøkkelen ikke gjenopprettelig.
  • Du kan opprette nøkler med konfigurerbar utløpsdato.
  • Hvis du mistenker at en nøkkel er kompromittert, tilbakekall den umiddelbart fra panelet.

Nøkkel-livssyklus

Opprett en nøkkel:

  1. Gå til Innstillinger > Utviklere > API-nøkler
  2. Klikk Opprett nøkkel
  3. Tilordne et beskrivende navn (for eksempel regnskapsintegrasjon)
  4. Valgfritt: angi en utløpsdato i dager. Hvis tom, utløper ikke nøkkelen
  5. Kopier nøkkelen umiddelbart -- du vil ikke kunne se den igjen

Utløp:

Nøkler med utløpsdato slutter automatisk å fungere når fristen er nådd. Forespørsler med en utløpt nøkkel mottar en 401 Unauthorized.

Tilbakekall:

Du kan tilbakekalle en nøkkel når som helst fra Innstillinger > Utviklere > API-nøkler. Tilbakekallingen er umiddelbar og irreversibel: pågående forespørsler med den nøkkelen vil feile fra det øyeblikket.

Nøkkel-rotasjon:

For å rotere en nøkkel uten å avbryte tjenesten:

  1. Opprett en ny nøkkel med samme omfang
  2. Oppdater integrasjonen din til å bruke den nye nøkkelen
  3. Verifiser at forespørslene fungerer korrekt
  4. Tilbakekall den forrige nøkkelen

Overvåking:

Hver nøkkel viser datoen for siste bruk i Innstillinger-panelet. Gå jevnlig gjennom inaktive nøkler og tilbakekall de som ikke lenger brukes.


Rate limiting

Hver API-nøkkel har en grense på 100 forespørsler per minutt. Hvis denne overskrides, svarer API-en med en 429-kode:

{
"error": "Rate limit exceeded",
"message": "Maximum 100 requests per minute",
"retryAfter": 60
}

Rate limiting-headere

Alle API-svar inkluderer headere slik at du kan administrere grensen proaktivt:

HeaderBeskrivelseEksempel
X-RateLimit-LimitTillatte forespørsler per minutt100
X-RateLimit-RemainingGjenstående forespørsler i gjeldende vindu87
X-RateLimit-ResetUnix tidsstempel (sekunder) for når vinduet tilbakestilles1709312400

Eksempel på svar med rate limiting-headere:

HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1709312400
Content-Type: application/json

Håndtering av 429-kode:

Når du mottar en 429, bruk headerne til å beregne hvor lenge du skal vente før du prøver igjen:

async function fetchWithRateLimit(url, options) {
const response = await fetch(url, options);

if (response.status === 429) {
const resetTimestamp = response.headers.get('X-RateLimit-Reset');
const waitMs = (Number(resetTimestamp) * 1000) - Date.now();
await new Promise(resolve => setTimeout(resolve, Math.max(waitMs, 1000)));
return fetch(url, options);
}

return response;
}

Anbefalinger:

  • Hvis du mottar en 429, vent til tidsstempelet angitt i X-RateLimit-Reset før du prøver på nytt.
  • Overvåk X-RateLimit-Remaining for å bremse forespørslene før du når grensen.
  • Fordel forespørslene over tid i stedet for å sende ut i byger.

Forespørsel-størrelse

Kroppen i POST-, PUT- og PATCH-forespørsler kan ikke overskride 1 MB. Større forespørsler mottar en 413-kode.


Ressurser

API-en eksponerer 7 hovedressurser: invoices, expenses, clients, products, quotes, vendors og webhooks. Alle støtter komplette CRUD-operasjoner (GET, POST, PUT/PATCH, DELETE). I tillegg har kunder CRM-underkategorier: contacts, activities og notes.

PATCH vs PUT

Både PUT og PATCH godtar delvise oppdateringer. Du trenger ikke å sende hele ressursen -- bare feltene du ønsker å endre.

Fakturaer (/invoices)

List fakturaer

GET /v1/invoices

Spørreparametre:

ParameterTypeStandardBeskrivelse
limitinteger50Resultater per side (maksimalt 100)
offsetinteger0Antall resultater å hoppe over (maksimalt 10 000)
statusstring--Filtrer etter status: utkast, sendt, betalt, forfalt, kansellert
fromstring--Startdato (ISO 8601: YYYY-MM-DD). Filtrerer etter issueDate
tostring--Sluttdato (ISO 8601: YYYY-MM-DD). Filtrerer etter issueDate

Eksempel:

curl "https://api.frihet.io/v1/invoices?limit=10&status=paid&from=2026-01-01&to=2026-03-31" \
-H "X-API-Key: fri_tu-clave-aqui"

Svar (200):

{
"data": [
{
"id": "abc123",
"clientName": "Acme S.L.",
"items": [
{ "description": "Consultoria", "quantity": 10, "unitPrice": 75 }
],
"status": "paid",
"issueDate": "2026-01-15",
"dueDate": "2026-02-15",
"taxRate": 21,
"notes": "",
"createdAt": "2026-01-15T10:30:00.000Z",
"updatedAt": "2026-01-20T14:00:00.000Z"
}
],
"total": 42,
"limit": 10,
"offset": 0
}

Hent faktura

GET /v1/invoices/:id
curl https://api.frihet.io/v1/invoices/abc123 \
-H "X-API-Key: fri_tu-clave-aqui"

Svar (200):

{
"id": "abc123",
"clientName": "Acme S.L.",
"items": [
{ "description": "Consultoria", "quantity": 10, "unitPrice": 75 }
],
"status": "paid",
"issueDate": "2026-01-15",
"dueDate": "2026-02-15",
"taxRate": 21,
"notes": "",
"createdAt": "2026-01-15T10:30:00.000Z",
"updatedAt": "2026-01-20T14:00:00.000Z"
}

Opprett faktura

POST /v1/invoices

Obligatoriske felt:

FeltTypeBeskrivelse
clientNamestringKundenavn (maks 10 000 tegn)
itemsarrayListe over fakturalinjer. Hver linje: { description, quantity, unitPrice }

Valgfrie felt:

FeltTypeBeskrivelse
statusstringutkast (standard), sendt, betalt, forfalt, kansellert
issueDatestringUtstedelsesdato (ISO 8601). Standard: i dag
dueDatestringForfallsdato (ISO 8601)
notesstringInterne notater (maks 10 000 tegn)
taxRatenumberSkatteprosent (0-100). Eks: 21 for 21% mva

Struktur for hver linje (items[]):

FeltTypeObligatoriskBeskrivelse
descriptionstringJaBeskrivelse av konseptet (maks 10 000 tegn)
quantitynumberJaAntall
unitPricenumberJaEnhetspris
curl -X POST https://api.frihet.io/v1/invoices \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"clientName": "Acme S.L.",
"items": [
{ "description": "Desarrollo web", "quantity": 40, "unitPrice": 60 }
],
"dueDate": "2026-03-01",
"taxRate": 21,
"notes": "Proyecto Q1 2026"
}'

Svar (201):

{
"id": "def456",
"clientName": "Acme S.L.",
"items": [
{ "description": "Desarrollo web", "quantity": 40, "unitPrice": 60 }
],
"status": "draft",
"issueDate": "2026-02-12",
"dueDate": "2026-03-01",
"taxRate": 21,
"notes": "Proyecto Q1 2026",
"createdAt": "2026-02-12T09:00:00.000Z",
"updatedAt": "2026-02-12T09:00:00.000Z"
}

Oppdater faktura (PUT eller PATCH)

PUT /v1/invoices/:id
PATCH /v1/invoices/:id

Du trenger bare å sende feltene du ønsker å endre. Felter som ikke er inkludert forblir uendret.

curl -X PATCH https://api.frihet.io/v1/invoices/def456 \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"status": "sent",
"notes": "Enviada al cliente"
}'

Svar (200): Oppdatert fakturaobjekt.

caution

Hvis du sender items, må du sende hele arrayet -- partielle oppdateringer av individuelle linjer er ikke tillatt.

Slett faktura

DELETE /v1/invoices/:id
curl -X DELETE https://api.frihet.io/v1/invoices/def456 \
-H "X-API-Key: fri_tu-clave-aqui"

Svar: 204 No Content

Last ned faktura i PDF

GET /v1/invoices/:id/pdf

Returnerer fakturaens PDF som application/pdf med Content-Disposition: attachment-headeren.

curl -o factura.pdf https://api.frihet.io/v1/invoices/abc123/pdf \
-H "X-API-Key: fri_tu-clave-aqui"

Send faktura via e-post

POST /v1/invoices/:id/send

Sender fakturaen til den spesifiserte mottakeren via Resend. Hvis fakturaen er i utkast-status, oppdateres den automatisk til sendt.

Felt:

FeltTypeObligatoriskBeskrivelse
recipientEmailstringJaE-postadresse til mottaker (maks 255 tegn)
recipientNamestringNeiNavn på mottaker (maks 200 tegn)
customMessagestringNeiEgendefinert melding i e-postens brødtekst (maks 5 000 tegn)
localestringNeiE-postens språk: es (standard) eller en
curl -X POST https://api.frihet.io/v1/invoices/abc123/send \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"recipientEmail": "admin@acme.es",
"recipientName": "Departamento de Contabilidad",
"locale": "es"
}'

Svar (200):

{ "success": true, "messageId": "re_abc123..." }

Merk faktura som betalt

POST /v1/invoices/:id/paid
FeltTypeObligatoriskBeskrivelse
paidDatestringNeiBetalingsdato (ISO 8601). Standard: i dag
curl -X POST https://api.frihet.io/v1/invoices/abc123/paid \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{ "paidDate": "2026-03-15" }'

Svar (200):

{ "success": true, "status": "paid", "paidAt": "2026-03-15" }

Utgifter (/expenses)

List utgifter

GET /v1/expenses

Spørreparametre:

ParameterTypeStandardBeskrivelse
limitinteger50Resultater per side (maksimalt 100)
offsetinteger0Antall resultater å hoppe over
fromstring--Startdato (ISO 8601). Filtrerer etter date
tostring--Sluttdato (ISO 8601). Filtrerer etter date
curl "https://api.frihet.io/v1/expenses?limit=20&from=2026-01-01" \
-H "X-API-Key: fri_tu-clave-aqui"

Svar (200):

{
"data": [
{
"id": "exp789",
"description": "Licencia Adobe Creative Cloud",
"amount": 59.99,
"category": "software",
"date": "2026-02-01",
"vendor": "Adobe Inc.",
"taxDeductible": true,
"createdAt": "2026-02-01T10:00:00.000Z",
"updatedAt": "2026-02-01T10:00:00.000Z"
}
],
"total": 15,
"limit": 20,
"offset": 0
}

Hent utgift

GET /v1/expenses/:id

Opprett utgift

POST /v1/expenses

Obligatoriske felt:

FeltTypeBeskrivelse
descriptionstringBeskrivelse av utgiften (maks 10 000 tegn)
amountnumberUtgiftsbeløp

Valgfrie felt:

FeltTypeBeskrivelse
categorystringKategori for utgiften (maks 10 000 tegn)
datestringUtgiftsdato (ISO 8601). Standard: i dag
vendorstringLeverandør (maks 10 000 tegn)
taxDeductiblebooleanOm utgiften er fradragsberettiget
curl -X POST https://api.frihet.io/v1/expenses \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"description": "Licencia Adobe Creative Cloud",
"amount": 59.99,
"category": "software",
"date": "2026-02-01",
"vendor": "Adobe Inc.",
"taxDeductible": true
}'

Svar (201):

{
"id": "exp789",
"description": "Licencia Adobe Creative Cloud",
"amount": 59.99,
"category": "software",
"date": "2026-02-01",
"vendor": "Adobe Inc.",
"taxDeductible": true,
"createdAt": "2026-02-12T09:15:00.000Z",
"updatedAt": "2026-02-12T09:15:00.000Z"
}

Oppdater utgift (PUT eller PATCH)

PUT /v1/expenses/:id
PATCH /v1/expenses/:id
curl -X PATCH https://api.frihet.io/v1/expenses/exp789 \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{ "amount": 65.99, "taxDeductible": false }'

Svar (200): Oppdatert utgiftsobjekt.

Slett utgift

DELETE /v1/expenses/:id

Svar: 204 No Content


Kunder (/clients)

List kunder

GET /v1/clients

Godtar limit, offset, from og to (filtrerer etter createdAt).

curl "https://api.frihet.io/v1/clients?limit=50" \
-H "X-API-Key: fri_tu-clave-aqui"

Hent kunde

GET /v1/clients/:id

Opprett kunde

POST /v1/clients

Obligatoriske felt:

FeltTypeBeskrivelse
namestringKundenavn (maks 10 000 tegn)

Valgfrie felt:

FeltTypeBeskrivelse
emailstringKontakt-e-post
phonestringTelefon
taxIdstringOrg.nr/MVA-nr
addressobjectAdresse (se struktur nedenfor)

Struktur for address:

FeltTypeBeskrivelse
streetstringGate og nummer
citystringBy
statestringProvins eller stat
postalCodestringPostnummer
countrystringLand

Alle felt i address er valgfrie.

curl -X POST https://api.frihet.io/v1/clients \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme S.L.",
"email": "admin@acme.es",
"taxId": "B12345678",
"address": {
"street": "Calle Gran Via 42",
"city": "Madrid",
"postalCode": "28013",
"country": "ES"
}
}'

Svar (201):

{
"id": "cli001",
"name": "Acme S.L.",
"email": "admin@acme.es",
"taxId": "B12345678",
"address": {
"street": "Calle Gran Via 42",
"city": "Madrid",
"postalCode": "28013",
"country": "ES"
},
"createdAt": "2026-02-12T09:30:00.000Z",
"updatedAt": "2026-02-12T09:30:00.000Z"
}

Oppdater kunde (PUT eller PATCH)

PUT /v1/clients/:id
PATCH /v1/clients/:id
curl -X PATCH https://api.frihet.io/v1/clients/cli001 \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{ "phone": "+34 912 345 678" }'

Svar (200): Oppdatert kundeobjekt.

Slett kunde

DELETE /v1/clients/:id

Svar: 204 No Content


CRM: Kontaktpersoner, Aktiviteter og Notater

Kunder har tre underkategorier for å administrere CRM-relasjoner: kontaktpersoner, aktiviteter og notater. Alle endepunkter krever en gyldig clientId i URL-en.

Kontaktpersoner (/v1/clients/:id/contacts)

List kontakter
GET /v1/clients/:id/contacts
curl "https://api.frihet.io/v1/clients/cli001/contacts" \
-H "X-API-Key: fri_tu-clave-aqui"
Hent kontakt
GET /v1/clients/:id/contacts/:contactId
curl "https://api.frihet.io/v1/clients/cli001/contacts/con001" \
-H "X-API-Key: fri_tu-clave-aqui"
Opprett kontakt
POST /v1/clients/:id/contacts

Obligatoriske felt:

FeltTypeBeskrivelse
namestringNavn på kontaktperson

Valgfrie felt:

FeltTypeBeskrivelse
emailstringE-postadresse til kontakten
phonestringTelefon
rolestringTittel eller rolle (f.eks. "Økonomidirektør")
isPrimarybooleanOm dette er kundens primære kontakt
curl -X POST https://api.frihet.io/v1/clients/cli001/contacts \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"name": "Maria Garcia",
"email": "maria@acme.es",
"phone": "+34 612 345 678",
"role": "Directora financiera",
"isPrimary": true
}'

Svar (201):

{
"id": "con001",
"name": "Maria Garcia",
"email": "maria@acme.es",
"phone": "+34 612 345 678",
"role": "Directora financiera",
"isPrimary": true,
"createdAt": "2026-03-15T10:00:00.000Z",
"updatedAt": "2026-03-15T10:00:00.000Z"
}
Oppdater kontakt
PATCH /v1/clients/:id/contacts/:contactId
curl -X PATCH https://api.frihet.io/v1/clients/cli001/contacts/con001 \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{ "role": "CEO" }'

Svar (200): Oppdatert kontaktobjekt.

Slett kontakt
DELETE /v1/clients/:id/contacts/:contactId
curl -X DELETE https://api.frihet.io/v1/clients/cli001/contacts/con001 \
-H "X-API-Key: fri_tu-clave-aqui"

Svar: 204 No Content

Aktiviteter (/v1/clients/:id/activities)

Aktivitetsloggen registrerer interaksjoner med en kunde. Systemaktiviteter (som invoice_created, quote_sent, osv.) genereres automatisk. Du kan også opprette manuelle aktiviteter.

Uforanderlige

Aktivitetene er uforanderlige. De kan ikke oppdateres eller slettes når de er opprettet.

List aktiviteter
GET /v1/clients/:id/activities
curl "https://api.frihet.io/v1/clients/cli001/activities" \
-H "X-API-Key: fri_tu-clave-aqui"
Hent aktivitet
GET /v1/clients/:id/activities/:activityId
curl "https://api.frihet.io/v1/clients/cli001/activities/act001" \
-H "X-API-Key: fri_tu-clave-aqui"
Opprett aktivitet
POST /v1/clients/:id/activities

Obligatoriske felt:

FeltTypeBeskrivelse
typestringAktivitetstype: call, email, meeting eller task
titlestringBeskrivende tittel på aktiviteten

Valgfrie felt:

FeltTypeBeskrivelse
descriptionstringDetaljert beskrivelse
metadataobjectTilleggsdata i fritt format
Aktivitetstyper

Typene call, email, meeting og task er for manuelt opprettede aktiviteter. Systemtyper som invoice_created, quote_sent eller expense_linked genereres automatisk og kan ikke opprettes via API.

curl -X POST https://api.frihet.io/v1/clients/cli001/activities \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"type": "call",
"title": "Llamada de seguimiento presupuesto Q2",
"description": "Comentamos las condiciones del presupuesto. Pendiente de confirmar.",
"metadata": {
"duration": "15min",
"outcome": "pending"
}
}'

Svar (201):

{
"id": "act001",
"type": "call",
"title": "Llamada de seguimiento presupuesto Q2",
"description": "Comentamos las condiciones del presupuesto. Pendiente de confirmar.",
"metadata": {
"duration": "15min",
"outcome": "pending"
},
"createdAt": "2026-03-15T14:30:00.000Z"
}

Notater (/v1/clients/:id/notes)

List notater
GET /v1/clients/:id/notes
curl "https://api.frihet.io/v1/clients/cli001/notes" \
-H "X-API-Key: fri_tu-clave-aqui"
Hent notat
GET /v1/clients/:id/notes/:noteId
curl "https://api.frihet.io/v1/clients/cli001/notes/note001" \
-H "X-API-Key: fri_tu-clave-aqui"
Opprett notat
POST /v1/clients/:id/notes

Obligatoriske felt:

FeltTypeBeskrivelse
contentstringInnholdet i notatet
curl -X POST https://api.frihet.io/v1/clients/cli001/notes \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"content": "Cliente interesado en plan Business. Contactar en abril para renovacion."
}'

Svar (201):

{
"id": "note001",
"content": "Cliente interesado en plan Business. Contactar en abril para renovacion.",
"createdAt": "2026-03-15T16:00:00.000Z",
"updatedAt": "2026-03-15T16:00:00.000Z"
}
Oppdater notat
PATCH /v1/clients/:id/notes/:noteId
curl -X PATCH https://api.frihet.io/v1/clients/cli001/notes/note001 \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"content": "Cliente interesado en plan Business. Reunion confirmada 5 de abril."
}'

Svar (200): Oppdatert notatobjekt.

Slett notat
DELETE /v1/clients/:id/notes/:noteId
curl -X DELETE https://api.frihet.io/v1/clients/cli001/notes/note001 \
-H "X-API-Key: fri_tu-clave-aqui"

Svar: 204 No Content


Produkter (/products)

List produkter

GET /v1/products

Godtar limit, offset, from og to (filtrerer etter createdAt).

Hent produkt

GET /v1/products/:id

Opprett produkt

POST /v1/products

Obligatoriske felt:

FeltTypeBeskrivelse
namestringNavn på produkt eller tjeneste (maks 10 000 tegn)
unitPricenumberEnhetspris

Valgfrie felt:

FeltTypeBeskrivelse
descriptionstringBeskrivelse (maks 10 000 tegn)
taxRatenumberSkatteprosent (0-100)
curl -X POST https://api.frihet.io/v1/products \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"name": "Hora de consultoria",
"unitPrice": 75,
"description": "Consultoria estrategica",
"taxRate": 21
}'

Svar (201):

{
"id": "prod001",
"name": "Hora de consultoria",
"unitPrice": 75,
"description": "Consultoria estrategica",
"taxRate": 21,
"createdAt": "2026-02-12T10:00:00.000Z",
"updatedAt": "2026-02-12T10:00:00.000Z"
}

Oppdater produkt (PUT eller PATCH)

PUT /v1/products/:id
PATCH /v1/products/:id
curl -X PATCH https://api.frihet.io/v1/products/prod001 \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{ "unitPrice": 85 }'

Svar (200): Oppdatert produktobjekt.

Slett produkt

DELETE /v1/products/:id

Svar: 204 No Content


Tilbud (/quotes)

List tilbud

GET /v1/quotes

Spørreparametre:

ParameterTypeStandardBeskrivelse
limitinteger50Resultater per side (maksimalt 100)
offsetinteger0Antall resultater å hoppe over
statusstring--Filtrer etter status: utkast, sendt, akseptert, avvist, utløpt
fromstring--Startdato (ISO 8601). Filtrerer etter issueDate
tostring--Sluttdato (ISO 8601). Filtrerer etter issueDate
curl "https://api.frihet.io/v1/quotes?status=sent" \
-H "X-API-Key: fri_tu-clave-aqui"

Hent tilbud

GET /v1/quotes/:id

Opprett tilbud

POST /v1/quotes

Obligatoriske felt:

FeltTypeBeskrivelse
clientNamestringKundenavn (maks 10 000 tegn)
itemsarrayLinjer i tilbudet. Hver linje: { description, quantity, unitPrice }

Valgfrie felt:

FeltTypeBeskrivelse
validUntilstringGyldig til dato (ISO 8601)
notesstringNotater eller betingelser (maks 10 000 tegn)
statusstringutkast (standard), sendt, akseptert, avvist, utløpt
curl -X POST https://api.frihet.io/v1/quotes \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"clientName": "Design Studio SL",
"items": [
{ "description": "Desarrollo web", "quantity": 80, "unitPrice": 60 },
{ "description": "Diseno UX", "quantity": 20, "unitPrice": 55 }
],
"validUntil": "2026-04-01",
"notes": "Incluye 2 rondas de revision"
}'

Svar (201):

{
"id": "quo001",
"clientName": "Design Studio SL",
"items": [
{ "description": "Desarrollo web", "quantity": 80, "unitPrice": 60 },
{ "description": "Diseno UX", "quantity": 20, "unitPrice": 55 }
],
"status": "draft",
"validUntil": "2026-04-01",
"notes": "Incluye 2 rondas de revision",
"createdAt": "2026-02-12T11:00:00.000Z",
"updatedAt": "2026-02-12T11:00:00.000Z"
}

Oppdater tilbud (PUT eller PATCH)

PUT /v1/quotes/:id
PATCH /v1/quotes/:id

Slett tilbud

DELETE /v1/quotes/:id

Svar: 204 No Content

Last ned tilbud i PDF

GET /v1/quotes/:id/pdf

Fungerer på samme måte som /invoices/:id/pdf. Returnerer application/pdf.

curl -o presupuesto.pdf https://api.frihet.io/v1/quotes/quo001/pdf \
-H "X-API-Key: fri_tu-clave-aqui"

Send tilbud via e-post

POST /v1/quotes/:id/send

Samme felt som /invoices/:id/send (recipientEmail, recipientName, customMessage, locale). Hvis tilbudet er i utkast-status, oppdateres det automatisk til sendt.


Batchoperasjoner (/batch)

Alle hovedressurser støtter batch-oppretting. Send et array med opptil 50 elementer i en enkelt forespørsel.

POST /v1/{resource}/batch

Støttede ressurser: invoices, expenses, clients, products, quotes

Forespørselens kropp:

{
"items": [
{ "clientName": "Acme SL", "items": [{ "description": "Hora consultoria", "quantity": 1, "unitPrice": 95 }] },
{ "clientName": "TechStart SL", "items": [{ "description": "Desarrollo web", "quantity": 8, "unitPrice": 60 }] }
]
}
curl -X POST https://api.frihet.io/v1/invoices/batch \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "clientName": "Acme SL", "items": [{ "description": "Consultoria", "quantity": 1, "unitPrice": 95 }] },
{ "clientName": "TechStart SL", "items": [{ "description": "Desarrollo", "quantity": 8, "unitPrice": 60 }] }
]
}'

Svar (207 Multi-Status):

{
"results": [
{ "status": 201, "data": { "id": "inv_001", "clientName": "Acme SL", "status": "draft" } },
{ "status": 201, "data": { "id": "inv_002", "clientName": "TechStart SL", "status": "draft" } }
],
"summary": { "total": 2, "succeeded": 2, "failed": 0 }
}

Hvis noen av elementene mislykkes valideringen, opprettes resten likevel. Individuelle feil returneres i results-arrayet:

{
"results": [
{ "status": 201, "data": { "id": "inv_001", "clientName": "Acme SL" } },
{ "status": 400, "error": { "message": "Missing required field: items" } }
],
"summary": { "total": 2, "succeeded": 1, "failed": 1 }
}

Grenser:

KonseptGrense
Elementer per batchMaks 50
Forespørsel-størrelseMaks 1 MB

Idempotens

POST-forespørsler godtar en Idempotency-Key-header for å forhindre duplisert opprettelse av ressurser ved nettverksforsøk. Hvis samme nøkkel sendes innen de neste 24 timene, returnerer API-en det originale svaret uten å utføre operasjonen på nytt.

curl -X POST https://api.frihet.io/v1/invoices \
-H "X-API-Key: fri_tu-clave-aqui" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{
"clientName": "Acme SL",
"items": [{ "description": "Consultoria", "quantity": 10, "unitPrice": 95 }]
}'

Oppførsel:

ScenarioResultat
Første forespørsel med nøkkelenRessursen opprettes normalt
Gjentatt forespørsel med samme nøkkel (innen 24 timer)Den originale responsen returneres, uten duplisering
Samme nøkkel etter 24 timerBehandles som en ny forespørsel

Svar-header:

Når API-en oppdager en gjentatt nøkkel, inkluderer den X-Idempotent-Replayed: true-headeren slik at forbrukeren vet at svaret er en kopi.

HTTP/1.1 201 Created
X-Idempotent-Replayed: true
Content-Type: application/json

Krav:

  • Nøkkelen må ha maksimalt 64 tegn
  • Vi anbefaler å bruke UUID v4
  • Gjelder kun for POST-forespørsler (opprette ressurser)

Søk

Liste-endepunktene støtter fulltekstsøk ved hjelp av parameteren q:

curl "https://api.frihet.io/v1/invoices?q=acme" \
-H "X-API-Key: fri_tu-clave-aqui"

Søket gjelder for ressursens hovedtekstfelt (kundenavn, beskrivelse, notater, osv.). Det kan kombineres med eksisterende filtre (status, from, to).


Intelligens-endepunkter

Disse endepunktene gir aggregerte data og forretningskontekst. De er spesielt nyttige for AI-agenter og eksterne dashboards.

Forretningskontekst (/context)

GET /v1/context

Returnerer en komplett forretningsoversikt, designet for å gi AI-agenter den nødvendige konteksten for å ta informerte beslutninger. Inkluderer finansiell oppsummering, nylig aktivitet, varsler og skatteinnstillinger.

curl https://api.frihet.io/v1/context \
-H "X-API-Key: fri_tu-clave-aqui"

Svar (200):

{
"business": {
"name": "BRTHLS Studio",
"taxId": "12345678A",
"fiscalZone": "canarias",
"currency": "EUR"
},
"summary": {
"revenue": { "invoiced": 15000, "paid": 12000, "pending": 2000, "overdue": 1000 },
"expenses": { "total": 4500 },
"profit": 7500,
"counts": { "invoices": 25, "clients": 12, "products": 5 }
},
"recentActivity": [
{ "type": "invoice.created", "id": "inv_001", "description": "Faktura for Acme SL", "timestamp": "2026-03-18T10:00:00Z" },
{ "type": "expense.created", "id": "exp_042", "description": "Adobe Creative Cloud", "timestamp": "2026-03-17T14:30:00Z" }
],
"alerts": [
{ "type": "overdue", "count": 2, "amount": 1000 },
{ "type": "tax_deadline", "model": "303", "dueDate": "2026-04-20" }
]
}

Månedlig resultatrapport (/monthly)

GET /v1/monthly?month=YYYY-MM

Returnerer resultatrapporten (P&L) for en spesifikk måned: fakturerte inntekter, utgifter per kategori, netto fortjeneste og sammenligning med forrige måned.

curl "https://api.frihet.io/v1/monthly?month=2026-02" \
-H "X-API-Key: fri_tu-clave-aqui"

Svar (200):

{
"month": "2026-02",
"revenue": {
"invoiced": 8500.00,
"collected": 6200.00,
"outstanding": 2300.00
},
"expenses": {
"total": 3100.00,
"byCategory": {
"software": 450.00,
"marketing": 800.00,
"office": 350.00,
"professional_services": 1500.00
}
},
"profit": 5400.00,
"comparison": {
"revenueChange": 12.5,
"expenseChange": -5.2,
"profitChange": 22.1
}
}

Kvartalsvise skattetall (/quarterly)

GET /v1/quarterly?quarter=YYYY-Q1

Returnerer kvartalsvise skattetall, forberedt for innlevering av Modelo 303 (mva) og Modelo 130 (inntektsskatt for selvstendig næringsdrivende). Inkluderer skattepliktig grunnlag, påløpte avgifter, fradragsberettigede avgifter og resultat av avregningen.

curl "https://api.frihet.io/v1/quarterly?quarter=2026-Q1" \
-H "X-API-Key: fri_tu-clave-aqui"

Svar (200):

{
"quarter": "2026-Q1",
"period": { "from": "2026-01-01", "to": "2026-03-31" },
"modelo303": {
"baseImponible21": 12000.00,
"cuotaDevengada21": 2520.00,
"baseImponible10": 0,
"cuotaDevengada10": 0,
"baseImponible4": 0,
"cuotaDevengada4": 0,
"totalDevengado": 2520.00,
"ivaDeducible": 980.00,
"resultado": 1540.00
},
"modelo130": {
"ingresos": 12000.00,
"gastos": 4500.00,
"rendimientoNeto": 7500.00,
"porcentaje": 20,
"cuota": 1500.00,
"retenciones": 0,
"pagosAnteriores": 0,
"resultado": 1500.00
}
}
tip

Endepunktene /context, /monthly og /quarterly er designet for å være det ideelle inngangspunktet for AI-agenter. De gir nødvendig informasjon i ett enkelt kall, uten behov for å konsultere flere individuelle endepunkter.


Finansielt dashbord (/summary)

GET /v1/summary

Returnerer en finansiell oppsummering av virksomheten: inntekter, utgifter, fortjeneste og tellere.

Spørreparametre:

ParameterTypeBeskrivelse
fromstringStartdato (ISO 8601)
tostringSluttdato (ISO 8601)
curl "https://api.frihet.io/v1/summary?from=2026-01-01&to=2026-03-31" \
-H "X-API-Key: fri_tu-clave-aqui"

Svar (200):

{
"period": { "from": "2026-01-01", "to": "2026-03-31" },
"revenue": {
"invoiced": 15000.00,
"paid": 12000.00,
"pending": 2000.00,
"overdue": 1000.00
},
"expenses": { "total": 4500.00 },
"profit": 7500.00,
"counts": {
"invoices": 25,
"quotes": 8,
"expenses": 42,
"clients": 12,
"products": 5
},
"invoicesByStatus": {
"draft": 3,
"sent": 5,
"paid": 15,
"overdue": 2
},
"overdue": { "count": 2, "amount": 1000.00 }
}

Feilkoder

API-en bruker standard HTTP-koder. Feilsvar inkluderer et JSON-objekt med feltene error og, valgfritt, message og details.

KodeBetydningBeskrivelse
400Bad RequestMangler et påkrevd felt, feil format eller ikke-tillatt felt
401UnauthorizedAPI-nøkkelen er ikke oppgitt, er ugyldig, har feil format eller har utløpt
403ForbiddenAPI-nøkkelen har ikke tillatelse til å få tilgang til denne ressursen
404Not FoundDen forespurte ressursen eksisterer ikke
405Method Not AllowedHTTP-metoden støttes ikke for dette endepunktet
413Payload Too LargeForespørselens kropp overskrider 1 MB
422Unprocessable EntityGyldige data, men serveren kan ikke behandle dem (f.eks.: skatteprofil ikke konfigurert)
429Too Many RequestsGrensen på 100 forespørsler per minutt er overskredet
500Internal Server ErrorIntern serverfeil

Struktur for feilsvar

Valideringsfeil (400):

{
"error": "Validation error",
"details": [
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": ["clientName"],
"message": "Required"
}
]
}

Valideringsfeil bruker Zod-formatet. path-feltet indikerer hvilket felt som inneholder feilen, og message beskriver problemet.

Ugyldig eller utløpt nøkkel (401):

{
"error": "Invalid or expired API key"
}

Ugyldig nøkkelformat (401):

{
"error": "Invalid API key format"
}

Ressurs ikke funnet (404):

{
"error": "Resource not found"
}

Ugyldig status i filter (400):

{
"error": "Invalid status filter",
"message": "Valid values: draft, sent, paid, overdue, cancelled"
}

Rate limit overskredet (429):

{
"error": "Rate limit exceeded",
"message": "Maximum 100 requests per minute",
"retryAfter": 60
}

Intern feil (500):

{
"error": "Internal server error"
}

Paginering

Liste-endepunktene returnerer paginerte resultater med følgende struktur:

{
"data": [],
"total": 142,
"limit": 50,
"offset": 0
}
  • total: totalt antall poster som oppfyller de anvendte filtrene
  • limit: antall poster returnert på denne siden (maksimalt 100)
  • offset: antall overhoppede poster (maksimalt 10 000)

For å hente neste side:

curl "https://api.frihet.io/v1/invoices?limit=50&offset=50" \
-H "X-API-Key: fri_tu-clave-aqui"

Resultatene sorteres etter ressursens naturlige dato i synkende rekkefølge (nyeste først):

  • Fakturaer og tilbud: issueDate
  • Utgifter: date
  • Kunder og produkter: createdAt

Streng validering

API-en bruker streng validering (Zod strict mode). Forespørsler med ukjente felt avvises med en 400-feil:

{
"error": "Validation error",
"details": [
{
"code": "unrecognized_keys",
"keys": ["campoInventado"],
"path": [],
"message": "Unrecognized key(s) in object: 'campoInventado'"
}
]
}

Dette forhindrer stille feil på grunn av skrivefeil i feltnavnene.


CORS

API-en støtter CORS for forespørsler fra nettleseren. Tillatte originer er:

  • https://app.frihet.io
  • https://frihet.io
  • https://www.frihet.io

For server-til-server-integrasjoner er CORS ikke relevant. Hvis du trenger å få tilgang til API-en fra et annet domene i nettleseren, bruk en proxy i din backend.


Sikkerhet-headere

Alle svar inkluderer sikkerhet-headere:

HeaderVerdi
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
X-XSS-Protection1; mode=block
X-Request-IdUnik forespørsel-ID (nyttig for feilsøking)

OAuth for MCP

Endepunktet POST /api/oauth/api-key tillater automatisk provisjonering av en API-nøkkel gjennom MCPs OAuth-flyt. MCP-serveren bruker dette endepunktet internt -- du trenger ikke å kalle det direkte.

Flyten:

  1. Brukeren autentiserer via Firebase Auth
  2. MCP-klienten sender Firebase-tokenet til /api/oauth/api-key
  3. Serveren returnerer en ny nøkkel fri_xxx... merket som "MCP OAuth"
  4. Nøkkelen utløper etter 365 dager

Grense: 5 aktive nøkler per bruker. Hvis grensen overskrides, svarer endepunktet med en 429.


Beste praksis

  1. Lagre API-nøkkelen sikkert. Inkluder den aldri i frontend-kode, offentlige repositoryer eller logger.
  2. Administrer rate limiting. Implementer eksponensiell backoff hvis du mottar en 429.
  3. Bruk paginering. Ikke be om alle poster samtidig; iterer med limit og offset.
  4. Verifiser svarkodene. Ikke anta at alle forespørsler vil være vellykkede.
  5. Roter nøkler periodisk. Opprett en ny nøkkel, oppdater integrasjonen din og tilbakekall den forrige.
  6. Bruk alltid HTTPS. Alle API-forespørsler må være over HTTPS.
  7. Bruk filtre. Parametrene status, from og to reduserer mengden overførte data.
  8. Dra nytte av PATCH. For partielle oppdateringer, send kun de endrede feltene.