Exact (exact_online v0.1.0)

Copy Markdown View Source

A client for the Exact Online REST API.

Quickstart

credentials = [
  client_id: System.fetch_env!("EXACT_CLIENT_ID"),
  client_secret: System.fetch_env!("EXACT_CLIENT_SECRET"),
  redirect_uri: "https://example.com/oauth/callback",
  region: :nl
]

# Send the user here, then exchange the code from the callback.
Exact.OAuth.authorize_url(credentials)
{:ok, token} = Exact.OAuth.exchange_code(code, credentials)
:ok = Exact.TokenStore.ETS.put(:default, token)

client =
  Exact.new(
    token_store: Exact.TokenStore.ETS,
    credentials: credentials
  )

# Every other endpoint needs a division.
{:ok, division} = Exact.System.Me.division(client)
client = Exact.Client.put_division(client, division)

{:ok, page} = Exact.CRM.Account.list(client, select: ["ID", "Name"], top: 10)
page.results

There is a runnable walkthrough in the Livebook notebook.

What this library does for you

  • refreshes the access token before it expires and once more on a 401, and persists the rotated refresh token through an Exact.TokenStore
  • unwraps the OData d envelope so you get maps and lists, and decodes /Date(...)/ strings into DateTime
  • follows the __next cursor, see Exact.Client.stream/3
  • turns non-2xx responses into Exact.Error with a :reason you can match on, and retries transient failures honoring Retry-After
  • reports the rate limit state Exact Online sends on every response, see Exact.RateLimit

What it does not do

Exact Online exposes around 600 resources. This library ships modules for the ones most integrations start with (Exact.System.Me, Exact.System.Division, Exact.CRM.Account, Exact.CRM.Contact, Exact.Sales.SalesInvoice, Exact.Financial.GLAccount) and covers the rest two ways: call any path with Exact.Client, or generate a module with Exact.Resource.

The XML API, the bulk and sync endpoints and webhook signature verification are not wrapped. Bulk and sync endpoints are reachable as ordinary paths, for example Exact.Client.stream(client, "bulk/CRM/Accounts").

Summary

Functions

Builds a client. Delegates to Exact.Client.new/1.

Functions

new(opts \\ [])

@spec new(keyword()) :: Exact.Client.t()

Builds a client. Delegates to Exact.Client.new/1.