BankingCircle.Cases (banking_circle v1.0.0)

Copy Markdown View Source

Case Management: Banking Circle raises a Case when it needs something from you — most commonly an RFI (Request for Information, usually a sanctions-screening hold on a payment) or a Recall Case (the counterparty bank asking you to return a payment they sent you). A case stays "OPEN" until you respond or a deadline passes, and not responding has real consequences (payment delay/rejection, account restriction), so treat list_cases/2 (or the case-opened webhook) as something worth polling/handling promptly rather than best-effort.

Navigation

list_cases/2 (GET /api/v1/cases) returns cases of every type with a links.self pointing you to the type-specific endpoint — e.g. an "RFI" case links to /api/v1/cases/rfi/{case-id}. This module gives you get_case/2 for the generic lookup and get_rfi_case/2 / get_recall_case/2 for the typed ones directly, so you don't have to round-trip through the generic endpoint if you already know the type.

This listing endpoint uses cursor-based pagination: once you've fetched a page with a given limit, only cursor and direction are valid on follow-up requests — the limit carries over from the initial request and cannot be changed mid-cursor.

Responding to an RFI

  1. get_rfi_case/2 — get the questions and subject/transaction context.
  2. For any attachment-type question, upload_attachment/4 first — each upload returns an attachmentId to reference in your answer.
  3. submit_rfi_answers/3 — either request a return (no answers needed) or answer every question asked (an empty string is an acceptable "I can't/won't answer" for a given question, but every question index must have a matching answer entry).

See BankingCircle.Cases.RFI for the answer-list building helpers.

Summary

Functions

Fetches a case by id regardless of type. The response's links.self field tells you which typed endpoint (get_rfi_case/2, get_recall_case/2, ...) to use for type-specific detail if you need it.

Fetches full detail for a Recall case (an incoming recall request from a counterparty bank).

Fetches full detail for an RFI case: questions, subject, and transaction context.

Lists all cases visible to you, regardless of type. Supports cursor pagination: pass :limit on the first call, then only :cursor and :direction (:next | :previous) on subsequent calls — other filters are locked in once a cursor is in use.

Lists the question types an RFI may ask, with their input format/limitations.

Submits your response to an RFI case. response is either

Uploads an attachment to a case (needed before answering any attachment-type RFI question). Returns {:ok, %{"attachmentId" => id}} (or however the API names it) — thread that id into the matching answer's attachmentIds list in submit_rfi_answers/3.

Types

case_id()

@type case_id() :: String.t()

client()

@type client() :: atom()

Functions

get_case(case_id, client \\ :default)

@spec get_case(case_id(), client()) ::
  {:ok, map()} | {:error, BankingCircle.Error.t()}

Fetches a case by id regardless of type. The response's links.self field tells you which typed endpoint (get_rfi_case/2, get_recall_case/2, ...) to use for type-specific detail if you need it.

get_recall_case(case_id, client \\ :default)

@spec get_recall_case(case_id(), client()) ::
  {:ok, map()} | {:error, BankingCircle.Error.t()}

Fetches full detail for a Recall case (an incoming recall request from a counterparty bank).

get_rfi_case(case_id, client \\ :default)

@spec get_rfi_case(case_id(), client()) ::
  {:ok, map()} | {:error, BankingCircle.Error.t()}

Fetches full detail for an RFI case: questions, subject, and transaction context.

list_cases(filters \\ [], client \\ :default)

@spec list_cases(
  keyword(),
  client()
) :: {:ok, map()} | {:error, BankingCircle.Error.t()}

Lists all cases visible to you, regardless of type. Supports cursor pagination: pass :limit on the first call, then only :cursor and :direction (:next | :previous) on subsequent calls — other filters are locked in once a cursor is in use.

rfi_question_types(client \\ :default)

@spec rfi_question_types(client()) :: {:ok, map()} | {:error, BankingCircle.Error.t()}

Lists the question types an RFI may ask, with their input format/limitations.

submit_rfi_answers(case_id, response, client \\ :default)

@spec submit_rfi_answers(case_id(), map(), client()) ::
  {:ok, map()} | {:error, BankingCircle.Error.t()}

Submits your response to an RFI case. response is either:

  • %{request_return: true} — indicate you want the payment returned, no answers needed, or
  • %{answers: [%{index: 0, answer: "...", attachment_ids: [...]}, ...]} — every question index the RFI asked must have a matching entry (an empty answer is acceptable if you can't/won't answer a particular question — see the moduledoc).

See BankingCircle.Cases.RFI.build_answers/1 for a convenience builder.

upload_attachment(case_id, content, filename, content_type \\ "application/octet-stream", client \\ :default)

@spec upload_attachment(case_id(), binary(), String.t(), String.t(), client()) ::
  {:ok, map()} | {:error, BankingCircle.Error.t()}

Uploads an attachment to a case (needed before answering any attachment-type RFI question). Returns {:ok, %{"attachmentId" => id}} (or however the API names it) — thread that id into the matching answer's attachmentIds list in submit_rfi_answers/3.

content is the raw file bytes; filename and content_type describe it for the multipart upload.