Transport for the Plaid API: environment selection, the credentialed post escape hatch, request-body building that drops unset fields, and Plaid's error object unwrapped into HttpError.

Per-call credentials. Every API-calling function in this package takes an optional trailing opts Map, resolved by resolve: opts first, then the plaid.* context variables, then the defaults. They are masked in call records and never written to ctx, so one run can act for many Plaid clients.

  • client-id, secret: the credentials for this call, always together
  • environment: "sandbox" or "production" for this call
  • plaid-version: the Plaid-Version for this call

A key that is present but blank or null is an Err naming it, never a fallback to context.

Item access_tokens, and the tokens Plaid mints, are masked in call records too.

Context Vars

Optional
  • plaid.client-id
  • plaid.secret
  • plaid.env
  • plaid.version

Values

REQUIRED_WHEN_PRESENT

REQUIRED_WHEN_PRESENT: Vec [
  "client-id",
  "secret",
  "environment"
]

TOKEN_FIELDS

TOKEN_FIELDS: Vec [
  "access_token",
  "public_token",
  "link_token"
]

Functions

blank-option

fn (opts: Map, names: Vec): Str?

The first of names that opts has with a blank or null value, else null.

build-request

fn (path: Str, body: Map, resolved: Map): ::hot::http/HttpRequest

The outgoing HttpRequest from resolved settings (see resolve), with the credentials in the JSON body. Pure; exposed for testing.

compact

fn (body: Map): Map

Drop null-valued keys from a request body. An options sub-object that is null or empty is dropped too, so Plaid never sees "options": null. Exposed for testing.

current-env

fn (): Str

The configured environment name: plaid.env, or "sandbox" when unset or empty.

env-base-url

fn (env: Str): Str

The base URL for a Plaid environment: "sandbox" or "production". Anything else errs (including the decommissioned "development"). Exposed for testing.

is-error-code

fn (e: Any, code: Str): Bool

True when e is a Plaid HttpError with this error_code (e.g. "ITEM_LOGIN_REQUIRED", "TRANSACTIONS_SYNC_MUTATION_DURING_PAGINATION").

mark-credentials

fn (opts: Map): Any

Mask the credentials in opts in this run's call records. Called first wherever opts arrives, so the records of the calls after it are masked too. Returns null.

mark-tokens

fn (body: Any): Any

Mask a request or response body's access_token, public_token and link_token in this run's call records. Returns the body unchanged.

non-blank

fn (value: Any): Str?

plaid-field

fn (body: Any, key: Str): Any

plaid-version

fn (): Str

The Plaid-Version header value: plaid.version, or ::plaid/PLAID_VERSION.

post

fn (path: Str, body: Map): Any
fn (path: Str, body: Map, opts: Map): Any
fn (path: Str, body: Map, client-id: Str, secret: Str): Any
fn (path: Str, body: Map, client-id: Str, secret: Str, env: Str): Any

POST a Plaid endpoint with credentials injected into the body and the Plaid-Version header set. Returns the decoded JSON body on 2xx, or an Err carrying HttpError. The escape hatch for endpoints not wrapped by this package.

Example

out ::plaid::api/post("/categories/get", {})

// For another Plaid client
out ::plaid::api/post("/categories/get", {}, {client-id: "tenant-id", secret: "tenant-secret"})

resolve

fn (opts: Map): Map

Credentials and settings for one call (see resolve-from). The credentials are masked in this run's call records, and nothing from opts is written to ctx.

Example

::plaid::api/resolve({client-id: "tenant-id", secret: "tenant-secret", environment: "production"}).base-url
// "https://production.plaid.com"
Context Vars: plaid.client-id, plaid.secret, plaid.env, plaid.version

resolve-from

fn (opts: Map, ctx-values: Map): Map

The one resolver, pure: {client-id, secret, base-url, plaid-version} for a call from opts first, then ctx-values (a Map of context variables), then defaults. An Err when a credential is not set, when client-id, secret or environment is in opts but blank or null, when opts has only one of client-id and secret (a tenant's id must not go out with the project's secret), or when the environment is unknown. Exposed for testing; resolve feeds it the context.

with-credentials

fn (body: Map, client-id: Str, secret: Str): Map

The full request body: client_id and secret first, then the (compacted) body. Exposed for testing.

Types

HttpError

HttpError type {
    status: Int,
    headers: Map,
    body: Any,
    error_type: Str?,
    error_code: Str?,
    error_message: Str?,
    display_message: Str?,
    request_id: Str?,
    documentation_url: Str?,
    suggested_action: Str?
}

A non-2xx Plaid response. status, headers and body as in the sibling packages, plus Plaid's error object lifted to the top: error_type (e.g. ITEM_ERROR, INVALID_REQUEST, RATE_LIMIT_EXCEEDED), error_code (e.g. ITEM_LOGIN_REQUIRED), error_message, display_message (safe to show end users, often null), request_id (quote it to Plaid support), documentation_url and suggested_action.