Test Status Coverage Status Hex Version Hex Docs

An Elixir client for the Plain GraphQL API.

Installation

Add ex_plain to your dependencies in mix.exs:

def deps do
  [
    {:ex_plain, "~> 0.3.0"}
  ]
end

Quick start

client = ExPlain.new(api_key: System.fetch_env!("PLAIN_API_KEY"))

# Look up a customer
{:ok, customer} = ExPlain.Customers.get_by_email(client, "alice@example.com")

# Create a thread
{:ok, thread} = ExPlain.Threads.create(client, %{
  customer_identifier: %{customer_id: customer.id},
  title: "Cannot log in"
})

Domains covered

ModuleOperations
ExPlain.Customersupsert, get, list, delete, manage groups
ExPlain.Threadscreate, assign, label, reply, change status
ExPlain.Companiesupsert, get, list
ExPlain.Tenantsupsert, get, list, manage customers
ExPlain.Tiersupsert, get, list
ExPlain.Labelslist label types, add/remove labels on threads
ExPlain.Eventscreate customer and thread timeline events
ExPlain.Userslist users, get current user
ExPlain.Webhookslist, create, update, delete webhook targets

Pagination

List operations follow the Relay cursor pagination convention. Pass first: and after: (or last: and before:) keyword options; the response is a map with :nodes and :page_info.

{:ok, page} = ExPlain.Customers.list(client, first: 50)
next_cursor = page.page_info.end_cursor
{:ok, page2} = ExPlain.Customers.list(client, first: 50, after: next_cursor)

Error handling

All functions return {:ok, result} or {:error, %ExPlain.Error{}}. Mutation errors from Plain (validation failures, permission errors) come back as {:error, %ExPlain.Error{type: :mutation_error}} with field-level detail when available.

case ExPlain.Customers.upsert(client, input) do
  {:ok, %{result: :created, customer: customer}} -> customer
  {:error, %ExPlain.Error{type: :mutation_error, message: msg}} -> {:error, msg}
  {:error, %ExPlain.Error{type: :forbidden}} -> {:error, :unauthorized}
end

Testing

Pass a plug: option to use Req.Test for HTTP stubbing without real network calls:

client = ExPlain.new(api_key: "test_key", plug: {Req.Test, __MODULE__})

Req.Test.stub(__MODULE__, fn conn ->
  Req.Test.json(conn, %{"data" => %{"customer" => %{"id" => "c_01", ...}}})
end)

Documentation

Full API documentation is available on HexDocs.