INTERVENTIO
Features Pricing Compare the plans
Register

API

Read and write your InterventIO data from your own software. Version 1 — stable.

Address and version

Everything lives under https://interventio.alienproject.org/api/v1. The version is in the URL and not in a header: you write it once in your configuration and you can see it, while a forgotten header sends requests to the wrong version without anyone noticing.

Authentication

A manager creates a token in Settings → API. It is shown once: we only keep its fingerprint. Send it on every request.

curl -H "Authorization: Bearer <token>" https://interventio.alienproject.org/api/v1/clienti

A token belongs to the person who created it and acts as them: it sees exactly what they see, and it stops working if they leave the company or their licence expires. It carries one of two abilities — lettura (read) or scrittura (write, which always includes read). Rate limit: 60 requests per minute, counted per user.

Responses and errors

Lists come back as data plus links and meta. Every error has the same shape: esito for your program, messaggio for whoever reads the log. Writes answer with esito too, even when they succeed, so you never have to tell cases apart from the status code alone.

esito HTTP When
creato 201 The record was created
aggiornato 200 The record was updated
gia_esistente 200 You repeated a creation we had already accepted
non_autenticato 401 No token, unknown token, or expired token
utente_non_attivo 403 The person the token belongs to no longer works there
solo_fornitori 403 The API is for service providers
licenza_scaduta 403 The licence is no longer valid
funzione_non_inclusa 403 The plan does not include the API
abilita_mancante 403 A read-only token tried to write
non_trovato 404 Wrong address, or a record that is not yours
metodo_non_ammesso 405 That address does not accept that method
validazione_fallita 422 Check errori for the offending fields
troppe_richieste 429 Slow down

A record belonging to another company answers 404, not 403. Saying "forbidden" would confirm that the id exists, which is a way of counting somebody else's documents.

Reading

Endpoint Filters of its own
GET /clienti · GET /clienti/{id} cerca, attivi
GET /commesse · GET /commesse/{id} cerca, id_cliente, attive
GET /rapportini · GET /rapportini/{id} id_cliente, stato, dal, al
GET /fatture · GET /fatture/{id} id_cliente, stato, dal, al

Every list also takes per_pagina (50 by default, 200 at most) and aggiornati_dopo. There is no parameter for choosing whose data you get: it is always the company the token belongs to. Field names are the ones in the database, the same as in the XLSX export — three vocabularies for one column would be three chances to get it wrong. Amounts are JSON numbers, dates are Y-m-d, moments are ISO 8601.

Detail responses carry the lines; lists do not. Invoices are the exception: totals (imponibile, iva, totale, totale_incassato, residuo) are on both, because reconciling payments should not mean opening one invoice at a time.

Staying in sync

Pass aggiornati_dopo to get only what changed. Every list hands back the moment to use next time:

{
  "data": [ … ],
  "meta": { "total": 128, "prossimo_aggiornati_dopo": "2026-07-31T09:14:03+00:00" }
}

Use that value, not the newest aggiornato_il you saw. Lists are ordered by id, so a record changed while you were paging may have an id you have already passed: a checkpoint computed from what you read would lose it forever, while the moment of the request picks it up next time. You may see a few records twice — that is the right way round to be wrong.

Writing

Needs a token with the scrittura ability.

Endpoint Notes
POST /clienti codice_esterno must be unique among your customers
PUT|PATCH /clienti/{id} Only the fields you send are touched
POST /commesse id_cliente must be one of your customers
PUT|PATCH /commesse/{id} id_cliente cannot be changed
POST /rapportini uuid is required and makes retries safe; optional esiti per system

PUT and PATCH do the same thing and update only what arrives. Strict PUT semantics would mean that a system syncing addresses wipes the VAT number of half an address book by omitting it. To clear a field, send null — something you write on purpose.

A POST that times out is the normal way HTTP fails. On intervention reports, send a uuid you generate: repeating the same call gives you back gia_esistente and the same document, never a duplicate. On customers and jobs that job is done by codice_esterno.

Check result per system. Next to impianti (the ids of the systems the report is about) you can send esiti: a list of {"id_impianto": 12, "esito": "non_conforme", "nota": "Gauge in the red"}, where esito is conforme, non_conforme, non_controllato or null. It is optional: a result for a system the report is not linked to is skipped. GET /rapportini/{id} returns the same information in impianti.

Invoices are read-only. Numbering, series and the rules about when a document may be issued belong to the application: handing them to an external client would mean exposing all of them. There is no DELETE either — nothing here is deleted, things are deactivated.

Webhooks

The other direction: we call you when something happens here, so you do not have to keep asking. Set them up in Settings → Webhooks.

{
  "evento": "fattura_emessa",
  "momento": "2026-07-31T09:14:03+00:00",
  "id_azienda": 12,
  "titolo": "Invoice issued",
  "messaggio": "Invoice FA/2026/00042 has been issued.",
  "oggetto": { "tipo": "FA", "id": 908, "numero_completo": "FA/2026/00042" }
}

oggetto is filled in for events about a document and is null for the others — licences, sign-ins, users — because documents are the only things this API can show you, and a reference to anything else would send you knocking at a door that does not exist.

Check the signature. Each call carries X-InterventIO-Momento and X-InterventIO-Firma. Redo the same sum with your secret and compare; refuse anything older than a few minutes.

firma = "sha256=" + hmac_sha256(momento + "." + body, secret)

The moment is inside the signature on purpose: signing the body alone would leave a captured call replayable months later with a signature that still checks out. Answer with any 2xx. We try five times — after a minute, five, thirty, then two hours — and after ten deliveries that fail in a row the webhook switches itself off, with a note on the customer's board saying why.

Version policy

Version 1 will not break. We may add endpoints, add fields to existing responses, and add optional parameters — so parse leniently and ignore fields you do not know. What we will not do inside v1 is remove or rename a field, change the type or meaning of one, make an optional parameter required, or change what an esito means. Anything that would require you to change your code ships as /api/v2, and v1 keeps working for at least twelve months after v2 appears. There is no v2 today: an unknown version answers non_trovato.

Changelog

  • 2026-07-31 — v1
    First release. Tokens and abilities; customers, jobs, intervention reports and invoices for reading; customers, jobs and intervention reports for writing; webhooks; Fatture in Cloud connector.

Login

Enable only on a personal device: you will stay signed in even after closing the browser. To end the session, log out.

Forgot your password?
or
Continue with Google Redirecting to Google...

Contact us for an Enterprise plan

Tell us about your needs and we'll get back to you as soon as possible.

Your email will NOT be shared with others.

Accepts international prefixes with + or 00.