Billberry kliendi liidese (API) kaudu saad oma ettevõtete nimel e-arveid saata ja neile saadetud e-arveid alla laadida. API kaudu saad näiteks e-poe või muu veebiteenuse oma klientidele e-arveid saatma panna. Samuti saab liidest kasutada raamatupidamistarkvara läbi, et e-arveid läbi Billberry saata ja vastu võtta.

Billberry ja API kasutamine sellisel viisil on tasuta. Kui sul veel kontot ei ole, registreeri Billberry kasutajaks.

Kliendi liidese kaudu saab e-arveid edastada vaid enda ettevõtete nimel. Kui soovid saata e-arveid oma klientide nimel, ilma et nad Billberry kliendiks peaks hakkama, võid hakata Billberry partneriks. Uuri Billberry partneri API juhendit ja võta ühendust.

Üldine

Billberry API tugineb HTTP ja REST printsiipidele. See tähendab ressursside-põhist aadresside struktuuri, semantilisi veakoode, MIME tüüpidega versioneerimist ja HTTP-s defineeritud funktsionaalsuse eelistamist teistele variantidele.

Billberry API aadress
https://api.billberry.ee

Põhjalikuma API spetsifikatsiooni leiab SwaggerHubist kui ka OpenAPI v3 formaadis (OpenAPI v3 enda spetsifikatsioon).

API spetsifikatsioon SwaggerHubis   API spetsifikatsioon OpenAPI v3 formaadis

Autentimine

API päringute autentimiseks on vajalik eelnevalt genereerida organisatsiooni API võti. Võtmeid saad hallata Billberry rakenduses organisatsiooni lehel, mille viited leiad konto ja seaded alt.

Võtit genereerides kuvatakse sulle võtme identifikaator ja parool. Näiteks:

Id 42
Võti 2ab96390c7dbe3439de74d0c9b0b1767

Identifikaatori alusel saad võtme hiljem tuvastada, kui soovid aeg-ajalt vanu võtmeid uute vastu vahetada. API võtmed on 16-baidised juhuslikud numbrid (kuvatud hex-formaadis), nii et soovi korral võid neid andmebaasis hoida ka binaarformaadis (BLOB).

HTTP päringute autentimine käib läbi Authorization päise ja Basic autentimise. Kasutajanimeks on API võtme identifikaator, parooliks võti. Näidisvõtme puhul oleks HTTP päring välja selline:

GET /invoices/received HTTP/1.1
Host: api.billberry.ee
Authorization: Basic NDI6MmFiOTYzOTBjN2RiZTM0MzlkZTc0ZDBjOWIwYjE3Njc=
Accept: application/vnd.billberry.invoice+json; v=1

Curliga pärides saab API võtme id ja parooli anda --user parameetriga:

curl --user 42:2ab96390c7dbe3439de74d0c9b0b1767 https://api.billberry.ee/…

Versioneerimine

API versioneerimine toimib läbi päringutele kaasa antud Accept ja Content-Type päiste ning MIME tüüpide. API spetsifikatsioonis leiad iga päringu juures sisu ja vastuse MIME tüübid ning nende skeemid.

Näiteks, arvete metadata esimese versiooni MIME tüüp on:

application/vnd.billberry.invoice+json; v=1

Ühe versiooni raames ei muudeta ega eemaldata kunagi kirjeldatud atribuute. JSON formaadis vastuste puhul võib aga arvestada, et atribuute võib juurde lisanduda, kuid see ei tohiks vastuste tõlgendamisel probleeme tekitada. Tundmatuid atribuute saab parsides lihtsalt ignoreerida.

Vigade käsitlus

Billberry API tagastab ebaõnnestunud päringute korral HTTP vastuse veakoodiga (status code vahemikus 400–599) ja põhjusega (status message/reason phrase).

Võimalikud veateated on kirjeldatud API spetsifikatsioonis iga päringu juures, kuid igaks juhuks tasub arvestada, et veasõnumeid võib lisanduda. Peamiselt on nad mõeldud arendajatele, kuigi vajadusel võib neid kuvada ka lõppkasutajatele — midagi salajast neis ei leidu.

Näiteks saates e-arvet ettevõttele, mis e-arveid vastu ei võta, vastab Billberry veakoodiga 409 ja põhjendusega Organization Doesn't Accept E-Invoices.

POST /invoices HTTP/1.1
Host: api.billberry.ee
Content-Type: application/xml
Accept: application/vnd.billberry.invoice+json; v=1

<E_Invoice></E_Invoice>
HTTP/1.1 409 Organization Doesn't Accept E-Invoices

Kui Accept päisesse lisada Billberry veateate MIME tüüp application/vnd.billberry.error+json; v=1, saab veaobjekti ka JSONis. Vea põhjendus leidub sel juhul peale staatuserea ka message atribuudis:

POST /invoices HTTP/1.1
Host: api.billberry.ee
Content-Type: application/xml
Accept:
  application/vnd.billberry.invoice+json; v=1,
  application/vnd.billberry.error+json; v=1

<E_Invoice></E_Invoice>
HTTP/1.1 409 Organization Doesn't Accept E-Invoices
Content-Type: application/vnd.billberry.error+json; v=1

{
  "message": "Organization Doesn't Accept E-Invoices"
}

Arvete saatmine ja vastuvõtmine

Arvete ressurss
/invoices
Arvete MIME tüüp
application/vnd.billberry.invoice+json; v=1

E-arve saatmine

Eesti e-arve standardile vastavaid e-arveid saad saata POST /invoices päringuga.

POST /invoices HTTP/1.1
Host: api.billberry.ee
Content-Type: application/xml
Accept: application/vnd.billberry.invoice+json; v=1
X-Send: immediately

<E_Invoice></E_Invoice>

Hetkel on toetatud vaid sünkroonne saatmine (päis X-Send: immediately). See tähendab, et päring ei saa vastust enne, kui teine operaator on arve vastu võtnud või tagasi lükanud. Tavaliselt võtab see alla sekundi. Sünkroonsus vähendab riski, et e-arve kaduma läheb, kui teine operaator peaks otsustama e-arvet hiljem mitte vastu võtta. Samuti lihtsustab see e-arve saatmise tehnilist poolt, sest API kliendina ei pea sa hakkama hiljem arve staatust pärima.

Teistele operaatoritele edastamise päringu maksimumkestus on 15 sekundit. Kui teine operaator selle aja sees ei vasta, saad veateate 504 ${Operator} Timeout, kus ${Operator} tähistab operaatori nime.

Kui e-arve on õigesti vormistatud ja ostja võtab e-arveid vastu, saad vastuseks 201 Sent.

HTTP/1.1 201 Sent
Content-Type: application/vnd.billberry.invoice+json; v=1

{
  "id": 42,
  "type": "debit",
  "registryCode": "16122596",
  "senderRegistryCode": "16122596",
  "senderName": "Seller Company OÜ",
  "receiverRegistryCode": "16122597",
  "receiverName": "Buyer Company OÜ",
  "number": "INV123",
  "date": "2020-06-18",
  "dueDate": "2020-06-25",
  "receivedAt": null,
  "receivedFromOperator": null,
  "receivedFileId": null,
  "receivedExternalId": null,
  "sentAt": "2020-06-18T13:37:42.666Z",
  "sentToOperator": "billberry",
  "sentFileId": "42",
  "sentExternalId": "43"
}

Võimalikud veateated on kirjeldatud API spetsifikatsioonis. Näiteks, üritades saata e-arvet ettevõttele, mis e-arveid vastu ei võta, vastab API 403 Organization Doesn't Accept E-Invoices. Kõikide atribuutide kirjelduse ja skeemi leiad API spetsifikatsioonist.

Curliga näeb e-arve XMLi saatmine selliselt, kui XML asub failis arve.xml:

curl https://api.billberry.ee/invoices \
  --user 42:2ab96390c7dbe3439de74d0c9b0b1767 \
  --data @arve.xml \
  --header "Accept: application/vnd.billberry.invoice+json; v=1" \
  --header "Content-Type: application/xml" \
  --header "X-Send: immediately"

E-arvete vastuvõtmine

Ettevõttele saadetud e-arveid näed GET /invoices/received päringuga.

GET /invoices/received HTTP/1.1
Host: api.billberry.ee
Accept: application/vnd.billberry.invoice+json; v=1
HTTP/1.1 200 OK
Content-Type: application/vnd.billberry.invoice+json; v=1
Link: </invoices/received?id%3e42>; rel="updates"

[{
  "id": 42,
  "type": "debit",
  "registryCode": "16122597",
  "senderRegistryCode": "16122596",
  "senderName": "Seller Company OÜ",
  "receiverRegistryCode": "16122597",
  "receiverName": "Buyer Company OÜ",
  "number": "INV123",
  "date": "2020-06-18",
  "dueDate": "2020-06-25",
  "receivedAt": null,
  "receivedFromOperator": null,
  "receivedFileId": null,
  "receivedExternalId": null,
  "sentAt": "2020-06-18T13:37:42.666Z",
  "sentToOperator": "billberry",
  "sentFileId": "42",
  "sentExternalId": "43"
}]

Väljade detailsema kirjelduse leiad API spetsifikatsioonist.

Sünkroniseerimine

Arvete regulaarseks sünkroniseerimiseks leiad vastuse Link päisest updates viite, mida pärides saad järgmine kord vastuseks vaid need arved, mis saabusid peale eelmist päringut.

Link: </invoices/received?id%3e42>; rel="updates"

Eelneva näite põhjal, peale esimest /invoices/received päringut leiad Link päisest /invoices/received?id%3e42. Järgmine kord arveid pärides kasuta seda aadressi. Kui vahepeal on saabunud uusi arveid, tagastatakse vaid need. Päringu lõpus võta taas Link päisest uus updates aadress ning pane järgmiseks korraks kõrvale. Iga päringu vastus viitab seega uuele updates lingile. Vanad updates lingid jäävad peale pärimist ka tööle, nii et ebaõnnestunud impordi korral võid lihtsalt sama aadressi uuesti proovida. Kõik laekunud arved saad alati originaalse /invoices/received päringuga.

Link päise formaati kirjeldavad RFC 8288 ja vanem RFC 5988.

Miks mitte kasutada kellaega arvete sünkroniseerimiseks nagu mõnes APIs?

Kellaaeg on veaohtlik sünkroniseerimise meetod nii teoorias kui praktikas. Esiteks pole arvutites kasutatavad kellaajad monotoonselt kasvavad (k.a UTC). UTC-le lisatakse regulaarselt liigsekundid, mille tulemusel hüppab kell sekundi võrra edasi või tagasi. Mõni hiljem laekunud arve võib seega saada laekumiskellaajaks varasema sekundi. Pärides arveid viimati laekunud arve kellaaja alusel jääks seega arveid vahele. Peale liigsekundite mõjutab serveri kellaaega ka ajasünkroniseerimine (NTP). Olukorras, kus serveri kell käis ette või jäi mingil põhjusel ajutiselt taha, võib taas toimuda paarisekundiline aja liikumine.

Kõige ohtlikum muster on aga ühel kohalikul e-arve operaatoril, kelle API kasutab sünkroniseerimiseks mitte ainult kellaaega, vaid lausa kohalikku kellaaega (stiilis 2021-06-18 13:37:42). See tähendab, et talveajale minemise öösel (mil keeratakse kella tunni võrra tagasi) jätab nende liides peale kellakeeramist vahemikul laekunud arved väljastamata.

Billberry sünkroniseerimise (updates päise) linke kasutades ei jää ükski arve vahele, sest need ei tugine kellaajal.

Uusi arveid tasub pärida kord 1–5 minuti tagant, sest kahjuks ei kipu e-arved teiste operaatorite juurest tihedamini saabuma. On ka operaatoreid, kel läheb arvete saatmiseks vähemalt 15–30 minutit.

Kui on soov laekunud arvetest sekundi jooksul teada saada, saab Billberry pakkuda ka Server-Sent Events lahendust eelnevalt kirjeldatud pollimise asemel. Anna huvist meilitsi teada.

Vastuvõetud e-arve XML

Saabunud arvete e-arve standardile vastava XMLi saad kätte GET /invoices/{invoiceId}.xml aadressilt.

GET /invoices/{invoiceId}.xml HTTP/1.1
Host: api.billberry.ee
Accept: application/xml
HTTP/1.1 200 OK
Content-Type: application/xml

<E_Invoice></E_Invoice>