Client for the Quickbase JSON RESTful API.
Build a client with new/1, then pass it to the API functions:
client = Quickbase.new(realm: "demo.quickbase.com", token: System.fetch_env!("QB_USER_TOKEN"))
{:ok, %{"data" => rows}} =
Quickbase.query_records(client,
from: "bck7gp3q2",
select: [3, 6, 7],
where: "{'6'.EX.'Done'}"
)All functions return {:ok, body} on HTTP 200 or {:error, reason},
where reason is a Quickbase.Error (non-200 response) or an exception
(transport error). Bang variants (query_records!/2, etc.) return the
body directly and raise on failure.
Working with rows
Quickbase returns records keyed by stringified field id
(%{"6" => %{"value" => "Done"}}). See value/2, label_index/1, and
by_label/3 for helpers that unwrap them.
Options
new/1 accepts:
:realm(required) — your realm hostname, e.g."demo.quickbase.com":token(required) — a Quickbase user token:user_agent— optionalUser-Agentheader value- any other option is forwarded to
Req.new/1(:plug,:finch,:receive_timeout, ...), so the client is easy to test withReq.Testand tune for production pools.
Read-only calls (query_records/2, run_report/3, list_fields/2,
list_tables/2) are retried on transient failures via Req's built-in
retry; mutations (upsert_records/3, delete_records/3) are not.
Summary
Functions
Unwraps the value of a field in a row by its label, using an index built
with label_index/1. Returns nil when the label is unknown.
Deletes records matching a query (DELETE /records).
Same as delete_records/3 but returns the body and raises on failure.
Builds a %{label => field id string} map from the "fields" list of a
response, for use with by_label/3.
Lists the fields of a table (GET /fields).
Same as list_fields/2 but returns the body and raises on failure.
Lists the tables of an app (GET /tables).
Same as list_tables/2 but returns the body and raises on failure.
Builds a client for the given realm and user token.
Queries records in a table (POST /records/query).
Same as query_records/2 but returns the body and raises on failure.
Runs a saved report (POST /reports/{id}/run).
Same as run_report/3 but returns the body and raises on failure.
Lazily streams all records matching a query, paging through
POST /records/query under the hood.
Inserts or updates records (POST /records).
Same as upsert_records/4 but returns the body and raises on failure.
Unwraps the value of a field in a row returned by query_records/2 or
run_report/3. Accepts the field id as integer or string.
Types
@type client() :: Req.Request.t()
@type response() :: {:ok, map() | list()} | {:error, Quickbase.Error.t() | Exception.t()}
Functions
Unwraps the value of a field in a row by its label, using an index built
with label_index/1. Returns nil when the label is unknown.
iex> idx = Quickbase.label_index([%{"id" => 6, "label" => "Status"}])
iex> Quickbase.by_label(%{"6" => %{"value" => "Done"}}, idx, "Status")
"Done"
Deletes records matching a query (DELETE /records).
Quickbase.delete_records(client, "bck7gp3q2", "{'3'.EX.'42'}")
Same as delete_records/3 but returns the body and raises on failure.
Builds a %{label => field id string} map from the "fields" list of a
response, for use with by_label/3.
iex> Quickbase.label_index([%{"id" => 6, "label" => "Status"}])
%{"Status" => "6"}
Lists the fields of a table (GET /fields).
Same as list_fields/2 but returns the body and raises on failure.
Lists the tables of an app (GET /tables).
Same as list_tables/2 but returns the body and raises on failure.
Builds a client for the given realm and user token.
Returns a Req.Request that the other functions in this module accept.
Queries records in a table (POST /records/query).
Options
:from(required) — table id:select— list of field ids to return:where— a Quickbase query string:sort_by— list of maps, e.g.[%{"fieldId" => 6, "order" => "ASC"}]:group_by— list of maps, e.g.[%{"fieldId" => 6, "grouping" => "equal-values"}]:skip/:top— pagination offset and page size
See stream_records/2 to page through large result sets lazily.
Same as query_records/2 but returns the body and raises on failure.
Runs a saved report (POST /reports/{id}/run).
Quickbase.run_report(client, 7, "bck7gp3q2")
Same as run_report/3 but returns the body and raises on failure.
@spec stream_records( client(), keyword() ) :: Enumerable.t()
Lazily streams all records matching a query, paging through
POST /records/query under the hood.
Takes the same options as query_records/2; :top controls the page
size (default 500) and :skip the starting offset. Emits individual
row maps. Raises on request failure mid-stream.
client |> Quickbase.stream_records(from: "bck7gp3q2", select: [3]) |> Enum.count()
Inserts or updates records (POST /records).
records is a list of row maps keyed by field id:
Quickbase.upsert_records(client, "bck7gp3q2", [
%{"6" => %{"value" => "Task name"}, "7" => %{"value" => 12}}
])Pass merge_field_id: to update existing records matching on that field,
and fields_to_return: to get field values back in the response.
Same as upsert_records/4 but returns the body and raises on failure.
Unwraps the value of a field in a row returned by query_records/2 or
run_report/3. Accepts the field id as integer or string.
iex> Quickbase.value(%{"6" => %{"value" => "Done"}}, 6)
"Done"